Compare commits
4 Commits
citadel-48
...
wip/tiling
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea901abd61 | ||
|
|
4e5e6aa7f8 | ||
|
|
8e587e2e42 | ||
|
|
93901dc32f |
@@ -1,27 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2021 The GTK Authors
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.[ch]]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
# For the legacy tabs which still exist in the code:
|
||||
tab_width = 8
|
||||
|
||||
[*.xml]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
[meson.build]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
[*.md]
|
||||
max_line_length = 80
|
||||
111
.gitignore
vendored
111
.gitignore
vendored
@@ -1,12 +1,103 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
Makefile.in.in
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
build-aux
|
||||
compile
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
intltool-extract.in
|
||||
intltool-merge.in
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
.deps
|
||||
50-mutter-navigation.xml
|
||||
50-mutter-system.xml
|
||||
50-mutter-windows.xml
|
||||
mutter.desktop
|
||||
mutter-wayland.desktop
|
||||
*.o
|
||||
*.a
|
||||
*.lo
|
||||
*.la
|
||||
.libs
|
||||
*.swp
|
||||
*.gir
|
||||
*.typelib
|
||||
stamp-h1
|
||||
*.gmo
|
||||
*.make
|
||||
*~
|
||||
**/tags.*
|
||||
subprojects/gvdb/
|
||||
subprojects/sysprof/
|
||||
__pycache__/
|
||||
.buildconfig
|
||||
.vscode
|
||||
runtime-dir
|
||||
build
|
||||
_build
|
||||
builddir
|
||||
stamp-it
|
||||
.intltool-merge-cache
|
||||
POTFILES
|
||||
po/*.pot
|
||||
libmutter.pc
|
||||
mutter
|
||||
mutter-restart-helper
|
||||
mutter-test-client
|
||||
mutter-test-runner
|
||||
mutter-test-unit-tests
|
||||
mutter-all.test
|
||||
org.gnome.mutter.gschema.valid
|
||||
org.gnome.mutter.gschema.xml
|
||||
org.gnome.mutter.wayland.gschema.valid
|
||||
org.gnome.mutter.wayland.gschema.xml
|
||||
testasyncgetprop
|
||||
testboxes
|
||||
testgradient
|
||||
m4/*
|
||||
INSTALL
|
||||
mkinstalldirs
|
||||
meta-enum-types.[ch]
|
||||
src/stamp-meta-enum-types.h
|
||||
src/meta-dbus-display-config.[ch]
|
||||
src/meta-dbus-idle-monitor.[ch]
|
||||
src/meta-dbus-login1.[ch]
|
||||
src/gtk-primary-selection-protocol.c
|
||||
src/gtk-primary-selection-server-protocol.h
|
||||
src/gtk-shell-protocol.c
|
||||
src/gtk-shell-server-protocol.h
|
||||
src/xdg-shell-unstable-v*-protocol.c
|
||||
src/xdg-shell-unstable-v*-server-protocol.h
|
||||
src/pointer-gestures-unstable-v*-protocol.c
|
||||
src/pointer-gestures-unstable-v*-server-protocol.h
|
||||
src/relative-pointer-unstable-v*-protocol.c
|
||||
src/relative-pointer-unstable-v*-server-protocol.h
|
||||
src/pointer-constraints-unstable-v*-protocol.c
|
||||
src/pointer-constraints-unstable-v*-server-protocol.h
|
||||
src/meta/meta-version.h
|
||||
doc/reference/*.args
|
||||
doc/reference/*.bak
|
||||
doc/reference/*.hierarchy
|
||||
doc/reference/*.interfaces
|
||||
doc/reference/*.prerequisites
|
||||
doc/reference/*.signals
|
||||
doc/reference/*.stamp
|
||||
doc/reference/html/
|
||||
doc/reference/xml/
|
||||
doc/reference/meta-decl-list.txt
|
||||
doc/reference/meta-decl.txt
|
||||
doc/reference/meta-overrides.txt
|
||||
doc/reference/meta-undeclared.txt
|
||||
doc/reference/meta-undocumented.txt
|
||||
doc/reference/meta-unused.txt
|
||||
doc/reference/meta-docs.sgml
|
||||
doc/reference/meta.types
|
||||
gtk-doc.m4
|
||||
intltool.m4
|
||||
libtool.m4
|
||||
ltoptions.m4
|
||||
ltsugar.m4
|
||||
ltversion.m4
|
||||
lt~obsolete.m4
|
||||
.dirstamp
|
||||
|
||||
835
.gitlab-ci.yml
835
.gitlab-ci.yml
@@ -1,835 +0,0 @@
|
||||
include:
|
||||
- remote: 'https://gitlab.gnome.org/Infrastructure/freedesktop-ci-templates/-/raw/145b1bc7ef1702d2bd71584010d7113c6786a506/templates/fedora.yml'
|
||||
- remote: 'https://gitlab.gnome.org/Infrastructure/freedesktop-ci-templates/-/raw/34f4ade99434043f88e164933f570301fd18b125/templates/ci-fairy.yml'
|
||||
- component: gitlab.gnome.org/GNOME/citemplates/release-service@master
|
||||
inputs:
|
||||
job-stage: deploy
|
||||
dist-job-name: "dist-mutter-tarball"
|
||||
tarball-artifact-path: $TARBALL_ARTIFACT_PATH
|
||||
- component: gitlab.gnome.org/GNOME/citemplates/gnomeos-build-sysext@1.0.0-alpha.1
|
||||
inputs:
|
||||
meson-options:
|
||||
-Dxwayland_initfd=enabled
|
||||
-Dprofiler=true
|
||||
-Dbash_completion=false
|
||||
|
||||
build-sysext:
|
||||
before_script:
|
||||
- .gitlab-ci/install-gnomeos-sysext-dependencies.sh $CI_PROJECT_DIR/extension
|
||||
# x86_64_v2 runners hang on pulling the docker image. This should be removed
|
||||
# when the runners are all updated.
|
||||
# https://gitlab.gnome.org/Infrastructure/Infrastructure/-/issues/1665
|
||||
tags:
|
||||
- x86_64_v3
|
||||
|
||||
stages:
|
||||
- review
|
||||
- prepare
|
||||
- code-review
|
||||
- build
|
||||
- test
|
||||
- analyze
|
||||
- docs
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
FDO_UPSTREAM_REPO: GNOME/mutter
|
||||
TARBALL_ARTIFACT_PATH: build/meson-dist/$CI_PROJECT_NAME-$CI_COMMIT_TAG.tar.xz
|
||||
|
||||
.skip-git-clone:
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
|
||||
.mutter.git-clone:
|
||||
extends:
|
||||
- .skip-git-clone
|
||||
variables:
|
||||
MUTTER_CLONE_PATH: $CI_BUILDS_DIR/$CI_PROJECT_PATH
|
||||
MUTTER_CLONE_DEPTH: 1
|
||||
before_script: |
|
||||
if [ -n "$MUTTER_CLONE_PATH" ]; then
|
||||
set -x
|
||||
uri="$CI_REPOSITORY_URL"
|
||||
if [ -n "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" ]; then
|
||||
uri="$CI_MERGE_REQUEST_SOURCE_PROJECT_URL.git"
|
||||
branch="$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"
|
||||
elif [ -n "$CI_COMMIT_TAG" ]; then
|
||||
branch="$CI_COMMIT_TAG"
|
||||
elif [ -n "$CI_COMMIT_BRANCH" ]; then
|
||||
branch="$CI_COMMIT_BRANCH"
|
||||
else
|
||||
branch="$CI_DEFAULT_BRANCH"
|
||||
fi
|
||||
if [ ! -d "$MUTTER_CLONE_PATH" ] || [ -z "$(ls -A "$MUTTER_CLONE_PATH")" ]; then
|
||||
git clone --depth $MUTTER_CLONE_DEPTH "$uri" "$MUTTER_CLONE_PATH" -b "$branch"
|
||||
elif [ ! -d "$MUTTER_CLONE_PATH/.git" ]; then
|
||||
git clone --bare --depth $MUTTER_CLONE_DEPTH "$uri" "$MUTTER_CLONE_PATH/.git" -b "$branch"
|
||||
if git -C "$MUTTER_CLONE_PATH" config --unset core.bare; then
|
||||
git -C "$MUTTER_CLONE_PATH" checkout
|
||||
else
|
||||
# For some weird reasons sometimes the fast-path could fail with
|
||||
# "fatal: not in a git directory" error, so handle it manually
|
||||
tmpdir=$(mktemp --directory --tmpdir mutter-XXXXXX)
|
||||
mkdir "$tmpdir/repo"
|
||||
mv "$MUTTER_CLONE_PATH/.git" "$tmpdir/repo/"
|
||||
git clone "$tmpdir/repo" "$tmpdir/src"
|
||||
mv "$tmpdir"/src/* "$tmpdir"/src/.* "$MUTTER_CLONE_PATH"
|
||||
rm -r "$tmpdir/repo"
|
||||
rm -rv "$tmpdir"
|
||||
fi
|
||||
fi
|
||||
set +x
|
||||
fi
|
||||
|
||||
.mutter.skip-git-clone:
|
||||
extends:
|
||||
- .skip-git-clone
|
||||
variables:
|
||||
MUTTER_CLONE_PATH: ''
|
||||
|
||||
.mutter.run-as-user:
|
||||
image:
|
||||
name: ${FDO_DISTRIBUTION_IMAGE}
|
||||
entrypoint:
|
||||
- 'runuser'
|
||||
- '-u'
|
||||
- !reference [.mutter.fedora@common, variables, MUTTER_USER]
|
||||
- '--'
|
||||
|
||||
.mutter.distribution-image:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
- .mutter.run-as-user
|
||||
|
||||
.mutter.fedora@common:
|
||||
extends:
|
||||
- .skip-git-clone
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: 41
|
||||
BASE_TAG: '2025-03-28.0'
|
||||
MUTTER_USER: 'meta-user'
|
||||
FDO_DISTRIBUTION_PACKAGES:
|
||||
accountsservice-devel
|
||||
clang
|
||||
gcovr
|
||||
gnome-shell
|
||||
itstool
|
||||
python3-docutils
|
||||
sassc
|
||||
uncrustify
|
||||
xorg-x11-server-Xvfb
|
||||
mesa-dri-drivers
|
||||
mesa-vulkan-drivers
|
||||
xorg-x11-proto-devel
|
||||
qemu-system-x86-core
|
||||
busybox
|
||||
zenity
|
||||
python3-dbusmock
|
||||
gnome-desktop-testing
|
||||
ruff
|
||||
mypy
|
||||
|
||||
FDO_DISTRIBUTION_EXEC: |
|
||||
set -e
|
||||
|
||||
# Create $MUTTER_USER
|
||||
useradd -u 9999 -b /opt/mutter -ms /bin/bash $MUTTER_USER
|
||||
|
||||
# Enable sudo for $MUTTER_USER
|
||||
echo "%$MUTTER_USER ALL = (ALL) NOPASSWD: ALL" > /etc/sudoers.d/99_mutter-user
|
||||
|
||||
# Drop problematic vulkan driver that interferes with CI;
|
||||
# see https://gitlab.gnome.org/GNOME/gtk/-/commit/7814d1fd75911
|
||||
rm /usr/share/vulkan/icd.d/powervr_mesa_icd.x86_64.json
|
||||
|
||||
dnf install -y 'dnf-command(builddep)'
|
||||
|
||||
dnf builddep -y mutter --setopt=install_weak_deps=False
|
||||
dnf builddep -y gnome-shell --setopt=install_weak_deps=False
|
||||
dnf builddep -y kernel --setopt=install_weak_deps=False
|
||||
dnf builddep -y gi-docgen --setopt=install_weak_deps=False
|
||||
dnf builddep -y wayland --setopt=install_weak_deps=False
|
||||
|
||||
./.gitlab-ci/install-meson-project.sh \
|
||||
https://gitlab.gnome.org/jadahl/catch.git \
|
||||
main
|
||||
|
||||
./.gitlab-ci/install-meson-project.sh \
|
||||
https://gitlab.gnome.org/GNOME/gi-docgen.git \
|
||||
main
|
||||
|
||||
./.gitlab-ci/install-common-dependencies.sh
|
||||
|
||||
rpm -e --nodeps gnome-bluetooth-libs-devel \
|
||||
mutter mutter-devel \
|
||||
gnome-shell \
|
||||
$NULL
|
||||
|
||||
# Work-around for podman-push aborting on permission issue
|
||||
# https://gitlab.gnome.org/Infrastructure/Infrastructure/-/issues/1247
|
||||
rm -rf /etc/pki/pesign/
|
||||
chmod -R a+rX /opt/mutter/$MUTTER_USER
|
||||
chmod -R a+rX /var/lib/gdm
|
||||
|
||||
# Ensure that we mark the project clone dir as safe directory
|
||||
git config --system --add safe.directory "$CI_PROJECT_DIR"
|
||||
|
||||
if [[ x"$(uname -m )" = "xx86_64" ]] ; then
|
||||
# deprecated header no longer included in openssl-devel
|
||||
dnf install -y openssl-devel-engine
|
||||
|
||||
if [ -n "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" ]; then
|
||||
git clone --depth $MUTTER_CLONE_DEPTH \
|
||||
$CI_MERGE_REQUEST_SOURCE_PROJECT_URL.git mutter-src \
|
||||
-b "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"
|
||||
elif [ -n "$CI_COMMIT_BRANCH" ]; then
|
||||
git clone --depth $MUTTER_CLONE_DEPTH \
|
||||
$CI_REPOSITORY_URL mutter-src -b "$CI_COMMIT_BRANCH"
|
||||
else
|
||||
git clone --depth $MUTTER_CLONE_DEPTH $CI_REPOSITORY_URL mutter-src
|
||||
fi
|
||||
meson setup build mutter-src -Dkvm_tests=true
|
||||
ninja -C build src/tests/kvm/bzImage
|
||||
mkdir -p /opt/mutter
|
||||
cp build/src/tests/kvm/bzImage /opt/mutter/bzImage
|
||||
|
||||
git clone https://github.com/arighi/virtme-ng.git
|
||||
cd virtme-ng
|
||||
git fetch --tags
|
||||
git checkout v1.8
|
||||
./setup.py install --prefix=/usr
|
||||
cd ..
|
||||
rm -rf virtme-ng
|
||||
rm -rf build mutter-src
|
||||
fi
|
||||
retry:
|
||||
max: 2
|
||||
when:
|
||||
- 'always'
|
||||
|
||||
default:
|
||||
# Cancel jobs if newer commits are pushed to the branch
|
||||
interruptible: true
|
||||
# Auto-retry jobs in case of infra failures
|
||||
retry:
|
||||
max: 1
|
||||
when:
|
||||
- 'runner_system_failure'
|
||||
- 'stuck_or_timeout_failure'
|
||||
- 'scheduler_failure'
|
||||
- 'api_failure'
|
||||
|
||||
.mutter.fedora@x86_64:
|
||||
extends:
|
||||
- .mutter.fedora@common
|
||||
- .mutter.git-clone
|
||||
variables:
|
||||
FDO_DISTRIBUTION_TAG: "x86_64-${BASE_TAG}"
|
||||
|
||||
.mutter.fedora@aarch64:
|
||||
extends:
|
||||
- .mutter.fedora@common
|
||||
- .mutter.git-clone
|
||||
variables:
|
||||
FDO_DISTRIBUTION_TAG: "aarch64-${BASE_TAG}"
|
||||
tags:
|
||||
- aarch64
|
||||
|
||||
workflow:
|
||||
rules:
|
||||
# Allow to switch from branch pipelines to MR pipelines seamlessly
|
||||
# https://docs.gitlab.com/ee/ci/jobs/job_control.html#avoid-duplicate-pipelines
|
||||
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
# Don't trigger a branch pipeline if there is an open MR
|
||||
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
|
||||
when: never
|
||||
- if: '$CI_COMMIT_BRANCH'
|
||||
- if: '$CI_COMMIT_TAG'
|
||||
|
||||
.pipeline-guard:
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
- if: '$CI_COMMIT_TAG'
|
||||
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
||||
- if: '$CI_COMMIT_BRANCH =~ /^gnome-[0-9-]+$/'
|
||||
# Avoid catchall `when: manual` rule which might
|
||||
# cause duplicate pipelines to be triggered.
|
||||
# https://docs.gitlab.com/ee/ci/jobs/job_control.html#avoid-duplicate-pipelines
|
||||
#
|
||||
# Also make it so pipelines without MR need to be started
|
||||
# manually, since their state will most likely be WIP
|
||||
- if: '$CI_COMMIT_BRANCH'
|
||||
when: 'manual'
|
||||
|
||||
.only-merge-requests:
|
||||
rules:
|
||||
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^$/'
|
||||
when: never
|
||||
- if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
|
||||
when: on_success
|
||||
|
||||
repo-sanity:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
stage: review
|
||||
variables:
|
||||
GIT_DEPTH: "1"
|
||||
script:
|
||||
- >
|
||||
if [[ -z "$CI_REGISTRY_IMAGE" ]] ;
|
||||
then
|
||||
.gitlab-ci/simple-junit-report.sh check-junit-report.xml \
|
||||
repo-sanity "The container registry should be enabled in the project general settings panel at $CI_PROJECT_URL/edit" ;
|
||||
exit 1 ;
|
||||
fi
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- check-junit-report.xml
|
||||
reports:
|
||||
junit: check-junit-report.xml
|
||||
rules:
|
||||
- !reference [.only-merge-requests, rules]
|
||||
|
||||
check-commit-log:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
stage: review
|
||||
variables:
|
||||
GIT_DEPTH: "100"
|
||||
script:
|
||||
ci-fairy check-commits --junit-xml=commit-message-junit-report.xml
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- commit-message-junit-report.xml
|
||||
reports:
|
||||
junit: commit-message-junit-report.xml
|
||||
rules:
|
||||
- !reference [.only-merge-requests, rules]
|
||||
|
||||
check-merge-request:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
- .skip-git-clone
|
||||
stage: review
|
||||
script:
|
||||
ci-fairy check-merge-request --require-allow-collaboration --junit-xml=check-merge-request-report.xml
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- check-merge-request-report.xml
|
||||
reports:
|
||||
junit: check-merge-request-report.xml
|
||||
rules:
|
||||
- !reference [.only-merge-requests, rules]
|
||||
|
||||
build-fedora-container@x86_64:
|
||||
extends:
|
||||
- .fdo.container-build@fedora@x86_64
|
||||
- .mutter.fedora@x86_64
|
||||
- .mutter.skip-git-clone
|
||||
stage: prepare
|
||||
rules:
|
||||
- !reference [.pipeline-guard, rules]
|
||||
|
||||
build-fedora-container@aarch64:
|
||||
extends:
|
||||
- .fdo.container-build@fedora@aarch64
|
||||
- .mutter.fedora@aarch64
|
||||
- .mutter.skip-git-clone
|
||||
stage: prepare
|
||||
rules:
|
||||
- !reference [.pipeline-guard, rules]
|
||||
when: manual
|
||||
|
||||
check-c-code-style:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
variables:
|
||||
MUTTER_CLONE_DEPTH: 200
|
||||
stage: code-review
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
script:
|
||||
git config --global --add safe.directory $CI_PROJECT_DIR ;
|
||||
git remote add target $CI_MERGE_REQUEST_PROJECT_URL.git ;
|
||||
git fetch target $CI_MERGE_REQUEST_TARGET_BRANCH_NAME ;
|
||||
export common_parent_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "target/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME") <(git rev-list --first-parent HEAD) | head -1) ;
|
||||
python3 -u ./check-style.py --dry-run --sha $common_parent_sha ;
|
||||
allow_failure: true
|
||||
rules:
|
||||
- !reference [.only-merge-requests, rules]
|
||||
|
||||
check-python-code-style:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
variables:
|
||||
PYTHON_FILES:
|
||||
tools/gdctl
|
||||
clutter/clutter/gen-keyname-table.py
|
||||
clutter/clutter/clutter-keysyms-update.py
|
||||
stage: code-review
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
script:
|
||||
- ruff format --line-length 80 --check $PYTHON_FILES
|
||||
- ruff check $PYTHON_FILES
|
||||
- mypy $PYTHON_FILES
|
||||
rules:
|
||||
- !reference [.only-merge-requests, rules]
|
||||
|
||||
.build-mutter-base:
|
||||
variables:
|
||||
BASE_MESON_OPTIONS:
|
||||
-Degl_device=true
|
||||
-Dwayland_eglstream=true
|
||||
-Dcatch=true
|
||||
|
||||
.build-mutter:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .build-mutter-base
|
||||
stage: build
|
||||
script:
|
||||
- meson setup . build
|
||||
--prefix /usr
|
||||
--werror
|
||||
--fatal-meson-warnings
|
||||
--warnlevel 2
|
||||
--wrap-mode nofallback
|
||||
-Dbuildtype=debugoptimized
|
||||
-Db_coverage=true
|
||||
-Ddocs=true
|
||||
$BASE_MESON_OPTIONS
|
||||
$EXTRA_MESON_OPTIONS
|
||||
- meson compile -C build
|
||||
- sudo meson install --dry-run -C build
|
||||
artifacts:
|
||||
expire_in: 1 day
|
||||
paths:
|
||||
- build
|
||||
|
||||
build-mutter@x86_64:
|
||||
variables:
|
||||
EXTRA_MESON_OPTIONS:
|
||||
-Dkvm_tests=true
|
||||
-Dkvm_kernel_image=/opt/mutter/bzImage
|
||||
extends:
|
||||
- .build-mutter
|
||||
- .mutter.fedora@x86_64
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
|
||||
build-mutter@aarch64:
|
||||
extends:
|
||||
- .build-mutter
|
||||
- .mutter.fedora@aarch64
|
||||
needs:
|
||||
- job: build-fedora-container@aarch64
|
||||
artifacts: false
|
||||
when: manual
|
||||
|
||||
build-without-opengl-and-glx@x86_64:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
stage: build
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
script:
|
||||
- meson setup . build
|
||||
--prefix /usr
|
||||
--werror
|
||||
--wrap-mode nofallback
|
||||
-Dbuildtype=debugoptimized
|
||||
-Dopengl=false
|
||||
-Dglx=false
|
||||
-Degl_device=true
|
||||
-Dwayland_eglstream=true
|
||||
-Dintrospection=false
|
||||
- meson compile -C build
|
||||
- sudo meson install --no-rebuild -C build
|
||||
artifacts:
|
||||
paths:
|
||||
- build/meson-logs
|
||||
|
||||
build-without-native-backend-and-wayland@x86_64:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
stage: build
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
script:
|
||||
- meson setup . build
|
||||
--prefix /usr
|
||||
--werror
|
||||
--wrap-mode nofallback
|
||||
-Dbuildtype=debugoptimized
|
||||
-Dnative_backend=false
|
||||
-Dudev=false
|
||||
-Dwayland=false
|
||||
-Dxwayland=false
|
||||
-Dtests=disabled
|
||||
-Dintrospection=false
|
||||
- meson compile -C build
|
||||
- sudo meson install --no-rebuild -C build
|
||||
artifacts:
|
||||
paths:
|
||||
- build/meson-logs
|
||||
|
||||
build-wayland-xwayland@x86_64:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
stage: build
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
script:
|
||||
- meson setup . build
|
||||
--prefix /usr
|
||||
--werror
|
||||
--wrap-mode nofallback
|
||||
-Dbuildtype=debugoptimized
|
||||
-Dwayland=true
|
||||
-Dxwayland=true
|
||||
-Dx11=false
|
||||
-Dtests=disabled
|
||||
-Dintrospection=false
|
||||
- meson compile -C build
|
||||
- sudo meson install --no-rebuild -C build
|
||||
artifacts:
|
||||
paths:
|
||||
- build/meson-logs
|
||||
|
||||
build-wayland-only@x86_64:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
stage: build
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
script:
|
||||
- meson setup . build
|
||||
--prefix /usr
|
||||
--werror
|
||||
--wrap-mode nofallback
|
||||
-Dbuildtype=debugoptimized
|
||||
-Dwayland=true
|
||||
-Dxwayland=false
|
||||
-Dx11=false
|
||||
-Dtests=disabled
|
||||
-Dintrospection=false
|
||||
- meson compile -C build
|
||||
- sudo meson install --no-rebuild -C build
|
||||
artifacts:
|
||||
paths:
|
||||
- build/meson-logs
|
||||
|
||||
.test-setup:
|
||||
variables:
|
||||
GSETTINGS_SCHEMA_DIR: "$CI_PROJECT_DIR/build/data"
|
||||
MUTTER_DEBUG_DUMMY_MODE_SPECS: "800x600@10.0"
|
||||
PIPEWIRE_DEBUG: 2
|
||||
PIPEWIRE_LOG: "$CI_PROJECT_DIR/build/meson-logs/pipewire.log"
|
||||
XVFB_SERVER_ARGS: "+iglx -noreset"
|
||||
G_SLICE: "always-malloc"
|
||||
MALLOC_CHECK_: "3"
|
||||
NO_AT_BRIDGE: "1"
|
||||
GTK_A11Y: "none"
|
||||
before_script:
|
||||
- !reference [.mutter.git-clone, before_script]
|
||||
|
||||
.test-mutter-base:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .test-setup
|
||||
stage: test
|
||||
after_script:
|
||||
- pushd build
|
||||
- gcovr --root=..
|
||||
--filter='\.\./src/'
|
||||
--filter='\.\./clutter/'
|
||||
--filter='\.\./cogl/'
|
||||
--filter='\.\./mtk/'
|
||||
--gcov-ignore-errors=no_working_dir_found
|
||||
--exclude='\.\./build/.*\.[ch]$' --exclude='.*/tests/.*\.[ch]$'
|
||||
--json --output=../coverage-${CI_JOB_NAME}.json
|
||||
- popd
|
||||
artifacts:
|
||||
expire_in: 1 day
|
||||
name: "mutter-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
|
||||
when: always
|
||||
paths:
|
||||
- build
|
||||
- coverage-*.json
|
||||
|
||||
.test-mutter:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .test-mutter-base
|
||||
script:
|
||||
- glib-compile-schemas $GSETTINGS_SCHEMA_DIR
|
||||
- mkdir -m 1777 /tmp/.X11-unix
|
||||
- ./src/tests/meta-dbus-runner.py
|
||||
--
|
||||
meson test
|
||||
-C build
|
||||
--setup plain
|
||||
--no-suite 'mutter/kvm'
|
||||
--no-suite 'gvdb'
|
||||
--no-rebuild
|
||||
--timeout-multiplier 10
|
||||
--print-errorlogs
|
||||
artifacts:
|
||||
reports:
|
||||
junit: "build/meson-logs/testlog-plain.junit.xml"
|
||||
|
||||
test-mutter@x86_64:
|
||||
extends:
|
||||
- .mutter.fedora@x86_64
|
||||
- .test-mutter
|
||||
tags:
|
||||
- asan
|
||||
needs:
|
||||
- build-mutter@x86_64
|
||||
|
||||
test-mutter-kvm@x86_64:
|
||||
extends:
|
||||
- .mutter.fedora@x86_64
|
||||
- .test-mutter-base
|
||||
tags:
|
||||
- kvm
|
||||
script:
|
||||
- meson test -C build
|
||||
--no-rebuild
|
||||
--timeout-multiplier 10
|
||||
--setup plain
|
||||
--suite 'mutter/kvm'
|
||||
--print-errorlogs
|
||||
needs:
|
||||
- build-mutter@x86_64
|
||||
artifacts:
|
||||
reports:
|
||||
junit: "build/meson-logs/testlog-plain.junit.xml"
|
||||
|
||||
test-mutter@aarch64:
|
||||
extends:
|
||||
- .mutter.fedora@aarch64
|
||||
- .test-mutter
|
||||
tags:
|
||||
- asan-aarch64
|
||||
needs:
|
||||
- build-mutter@aarch64
|
||||
when: manual
|
||||
|
||||
coverage:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
stage: analyze
|
||||
script:
|
||||
- compgen -G "coverage-*.json" > /dev/null || exit 0
|
||||
- mkdir coveragereport
|
||||
- gcovr --add-tracefile 'coverage-*.json'
|
||||
--html-details
|
||||
--html-theme github.blue
|
||||
--print-summary
|
||||
--output coveragereport/index.html
|
||||
- gcovr --add-tracefile 'coverage-*.json'
|
||||
--xml --output coveragereport/coverage.xml
|
||||
artifacts:
|
||||
expose_as: 'Coverage Report'
|
||||
paths:
|
||||
- coveragereport
|
||||
- coveragereport/index.html
|
||||
reports:
|
||||
coverage_report:
|
||||
coverage_format: cobertura
|
||||
# TODO: we may need to split this file once it will reach the
|
||||
# gitlab limit size of 10M, or it will stop working:
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/328772
|
||||
path: coveragereport/coverage.xml
|
||||
coverage: '/^lines: (\d+\.\d+\%)/'
|
||||
needs:
|
||||
- test-mutter@x86_64
|
||||
# - test-mutter@aarch64
|
||||
- test-mutter-kvm@x86_64
|
||||
|
||||
can-run-gnome-shell@x86_64:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
- .test-setup
|
||||
stage: test
|
||||
needs:
|
||||
- build-mutter@x86_64
|
||||
before_script:
|
||||
- !reference [.mutter.fedora@x86_64, before_script]
|
||||
- sudo meson install --no-rebuild -C build
|
||||
script:
|
||||
- .gitlab-ci/checkout-gnome-shell.sh
|
||||
- meson setup gnome-shell gnome-shell/build --prefix /usr -Dbuildtype=debugoptimized -Dman=false --werror --fatal-meson-warnings
|
||||
- sudo meson install -C gnome-shell/build
|
||||
- mkdir -m 1777 /tmp/.X11-unix
|
||||
- dbus-run-session -- meson test -C gnome-shell/build --no-rebuild --timeout-multiplier 5
|
||||
artifacts:
|
||||
expire_in: 7 day
|
||||
name: "mutter-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
|
||||
when: on_failure
|
||||
paths:
|
||||
- gnome-shell/build/meson-logs
|
||||
|
||||
test-mutter-coverity:
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "schedule" && $MUTTER_SCHEDULED_JOB == "coverity"'
|
||||
when: on_success
|
||||
- if: '$CI_COMMIT_BRANCH'
|
||||
when: 'manual'
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
stage: analyze
|
||||
allow_failure: true
|
||||
script:
|
||||
- .gitlab-ci/download-coverity-tarball.sh
|
||||
- CC=clang meson setup coverity-build -Dprofiler=false
|
||||
- ./coverity/cov-analysis-linux64-*/bin/cov-build --dir cov-int meson compile -C coverity-build
|
||||
- tar czf cov-int.tar.gz cov-int
|
||||
- curl https://scan.coverity.com/builds?project=mutter
|
||||
--form token=$COVERITY_TOKEN --form email=carlosg@gnome.org
|
||||
--form file=@cov-int.tar.gz --form version="`git describe --tags`"
|
||||
--form description="GitLab CI build"
|
||||
cache:
|
||||
key: coverity-tarball
|
||||
paths:
|
||||
- coverity
|
||||
|
||||
dist-mutter:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
- .mutter.fedora@x86_64
|
||||
- .build-mutter-base
|
||||
- .test-setup
|
||||
stage: deploy
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
script:
|
||||
- meson setup . build
|
||||
--prefix /usr
|
||||
--werror
|
||||
--wrap-mode nofallback
|
||||
-Dbuildtype=debugoptimized
|
||||
- glib-compile-schemas $GSETTINGS_SCHEMA_DIR
|
||||
- mkdir -m 1777 /tmp/.X11-unix
|
||||
- ./src/tests/meta-dbus-runner.py
|
||||
--
|
||||
meson dist -C build --include-subprojects
|
||||
artifacts:
|
||||
expire_in: 7 day
|
||||
name: "mutter-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
|
||||
when: always
|
||||
paths:
|
||||
- build/meson-private/dist-build/meson-logs
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE != "merge_request_event"'
|
||||
when: manual
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
changes:
|
||||
- "**/meson.build"
|
||||
- meson/*
|
||||
when: on_success
|
||||
- if: '$GITLAB_USER_LOGIN == "marge-bot"'
|
||||
when: on_success
|
||||
- if: '$CI_MERGE_REQUEST_ASSIGNEES == "marge-bot"'
|
||||
when: on_success
|
||||
|
||||
installed-tests-mutter@x86_64:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
- .mutter.fedora@x86_64
|
||||
- .build-mutter-base
|
||||
- .test-setup
|
||||
stage: deploy
|
||||
needs:
|
||||
- build-mutter@x86_64
|
||||
script:
|
||||
- meson install -C build --no-rebuild
|
||||
- mkdir -m 1777 /tmp/.X11-unix
|
||||
- mkdir installed-tests-logs
|
||||
- gnome-desktop-testing-runner -L installed-tests-logs mutter
|
||||
artifacts:
|
||||
expire_in: 7 day
|
||||
name: "mutter-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
|
||||
when: always
|
||||
paths:
|
||||
- installed-tests-logs
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE != "merge_request_event"'
|
||||
when: manual
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
changes:
|
||||
- "**/meson.build"
|
||||
- meson/*
|
||||
when: on_success
|
||||
- if: '$GITLAB_USER_LOGIN == "marge-bot"'
|
||||
when: on_success
|
||||
- if: '$CI_MERGE_REQUEST_ASSIGNEES == "marge-bot"'
|
||||
when: on_success
|
||||
|
||||
dist-mutter-tarball:
|
||||
extends: dist-mutter
|
||||
artifacts:
|
||||
expose_as: 'Get tarball here'
|
||||
name: "${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
|
||||
when: always
|
||||
paths:
|
||||
- $TARBALL_ARTIFACT_PATH
|
||||
rules:
|
||||
- if: '$CI_COMMIT_TAG'
|
||||
|
||||
reference:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
stage: docs
|
||||
needs:
|
||||
- build-mutter@x86_64
|
||||
script:
|
||||
- mkdir references
|
||||
- cp -r doc/website/* ./references
|
||||
- mv build/doc/reference/{clutter/clutter,cogl/cogl,meta/meta,mtk/mtk} references/
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
expose_as: 'Documentation'
|
||||
paths:
|
||||
- references/
|
||||
|
||||
pages:
|
||||
stage: deploy
|
||||
needs: ['reference']
|
||||
extends:
|
||||
- .skip-git-clone
|
||||
script:
|
||||
- mv references public/
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
rules:
|
||||
- if: ($CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH && $CI_PROJECT_NAMESPACE == "GNOME")
|
||||
@@ -1,56 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
fetch() {
|
||||
local remote=$1
|
||||
local ref=$2
|
||||
|
||||
git fetch --quiet --depth=1 $remote $ref 2>/dev/null
|
||||
}
|
||||
|
||||
gnome_shell_target=
|
||||
|
||||
echo -n Cloning into gnome-shell ...
|
||||
if git clone --quiet --depth=1 https://gitlab.gnome.org/GNOME/gnome-shell.git; then
|
||||
echo \ done
|
||||
else
|
||||
echo \ failed
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd gnome-shell
|
||||
|
||||
if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
|
||||
merge_request_remote=${CI_MERGE_REQUEST_SOURCE_PROJECT_URL//mutter/gnome-shell}
|
||||
merge_request_branch=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
|
||||
|
||||
echo -n Looking for $merge_request_branch on remote ...
|
||||
if fetch $merge_request_remote $merge_request_branch; then
|
||||
echo \ found
|
||||
gnome_shell_target=FETCH_HEAD
|
||||
else
|
||||
echo \ not found
|
||||
|
||||
echo -n Looking for $CI_MERGE_REQUEST_TARGET_BRANCH_NAME instead ...
|
||||
if fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME; then
|
||||
echo \ found
|
||||
gnome_shell_target=FETCH_HEAD
|
||||
else
|
||||
echo \ not found
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$gnome_shell_target" ]; then
|
||||
ref_remote=${CI_PROJECT_URL//mutter/gnome-shell}
|
||||
echo -n Looking for $CI_COMMIT_REF_NAME on remote ...
|
||||
if fetch $ref_remote $CI_COMMIT_REF_NAME; then
|
||||
echo \ found
|
||||
gnome_shell_target=FETCH_HEAD
|
||||
else
|
||||
echo \ not found
|
||||
gnome_shell_target=HEAD
|
||||
echo Using $gnome_shell_target instead
|
||||
fi
|
||||
fi
|
||||
|
||||
git checkout -q $gnome_shell_target
|
||||
@@ -1,23 +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
|
||||
- regex: '^[Cc]lose[sd]?:?\s*#[0-9]+'
|
||||
message: Closes instructions must be a full link
|
||||
- regex: '^[Ff]ix(e[sd]?)?:?\s*(#[0-9]+|https://)'
|
||||
message: \"Fixes\" should be used with commits, use \"Closes\" for issues
|
||||
@@ -1,38 +0,0 @@
|
||||
#!/usr/bin/env 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,167 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
usage() {
|
||||
cat <<-EOF
|
||||
Usage: $(basename $0) [OPTION…]
|
||||
|
||||
Install common dependencies to a base image or system extension
|
||||
|
||||
Options:
|
||||
--libdir=DIR Setup the projects with a different libdir
|
||||
--destdir=DIR Install the project to DIR, can be used
|
||||
several times to install to multiple destdirs
|
||||
|
||||
-h, --help Display this help
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
pkgconf() {
|
||||
local PKG_CONFIG_DIRS=(
|
||||
/usr/lib64/pkgconfig
|
||||
/usr/lib/pkgconfig
|
||||
/usr/share/pkgconfig
|
||||
)
|
||||
|
||||
local search_dirs=()
|
||||
for destdir in "${DESTDIRS[@]}"; do
|
||||
search_dirs+=( "${PKG_CONFIG_DIRS[@]/#/$destdir}" )
|
||||
done
|
||||
|
||||
ENV=(PKG_CONFIG_PATH=$(echo "${search_dirs[@]}" | tr ' ' :))
|
||||
|
||||
env "${ENV[@]}" pkgconf --env-only "$@"
|
||||
}
|
||||
|
||||
pip_install() {
|
||||
local pkg=$1
|
||||
|
||||
for destdir in "${DESTDIRS[@]}"; do
|
||||
local pypaths=($destdir/usr/lib*/python3*/site-packages)
|
||||
if ! pip3 list "${pypaths[@]/#/--path=}" | grep $pkg >/dev/null
|
||||
then
|
||||
sudo pip3 install --ignore-installed \
|
||||
--root-user-action ignore \
|
||||
--prefix $destdir/usr \
|
||||
$pkg
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
check_gsettings_key() {
|
||||
local schema=$1
|
||||
local key=$2
|
||||
|
||||
local rv=0
|
||||
|
||||
for destdir in "${DESTDIRS[@]}"; do
|
||||
local schemadir=$(realpath $destdir/usr/share/glib-2.0/schemas/)
|
||||
local targetdir=$(mktemp --directory)
|
||||
|
||||
if ! glib-compile-schemas --targetdir $targetdir $schemadir 2>/dev/null ||\
|
||||
! env -i "XDG_DATA_DIRS=/dev/null" \
|
||||
gsettings --schemadir $targetdir get $schema $key >/dev/null 2>&1
|
||||
then
|
||||
rv=1
|
||||
fi
|
||||
|
||||
rm -rf $targetdir
|
||||
done
|
||||
|
||||
return $rv
|
||||
}
|
||||
|
||||
TEMP=$(getopt \
|
||||
--name=$(basename $0) \
|
||||
--options='h' \
|
||||
--longoptions='libdir:' \
|
||||
--longoptions='destdir:' \
|
||||
--longoptions='help' \
|
||||
-- "$@")
|
||||
|
||||
eval set -- "$TEMP"
|
||||
unset TEMP
|
||||
|
||||
OPTIONS=()
|
||||
DESTDIRS=()
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
--libdir)
|
||||
OPTIONS+=( --libdir=$2 )
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--destdir)
|
||||
DESTDIRS+=( $2 )
|
||||
shift 2
|
||||
;;
|
||||
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ ${#DESTDIRS[@]} == 0 ]] && DESTDIRS+=( / )
|
||||
OPTIONS+=( "${DESTDIRS[@]/#/--destdir=}" )
|
||||
|
||||
SCRIPTS_DIR="$(dirname $0)"
|
||||
|
||||
if ! pkgconf --atleast-version 48.alpha gsettings-desktop-schemas
|
||||
then
|
||||
./$SCRIPTS_DIR/install-meson-project.sh \
|
||||
"${OPTIONS[@]}" \
|
||||
https://gitlab.gnome.org/GNOME/gsettings-desktop-schemas.git \
|
||||
master
|
||||
fi
|
||||
|
||||
if ! pkgconf --atleast-version 1.3.901 libeis-1.0
|
||||
then
|
||||
./$SCRIPTS_DIR/install-meson-project.sh \
|
||||
"${OPTIONS[@]}" \
|
||||
https://gitlab.freedesktop.org/libinput/libei.git \
|
||||
1.3.901
|
||||
fi
|
||||
|
||||
pip_install argcomplete
|
||||
|
||||
if ! check_gsettings_key org.gnome.login-screen banner-message-source
|
||||
then
|
||||
./$SCRIPTS_DIR/install-meson-project.sh \
|
||||
"${OPTIONS[@]}" \
|
||||
https://gitlab.gnome.org/GNOME/gdm.git \
|
||||
main
|
||||
fi
|
||||
|
||||
if ! pkgconf --atleast-version 1.83.4 gjs-1.0
|
||||
then
|
||||
./$SCRIPTS_DIR/install-meson-project.sh \
|
||||
"${OPTIONS[@]}" \
|
||||
https://gitlab.gnome.org/GNOME/gjs.git \
|
||||
master
|
||||
fi
|
||||
|
||||
if ! pkgconf --atleast-version 1.41 wayland-protocols
|
||||
then
|
||||
./$SCRIPTS_DIR/install-meson-project.sh \
|
||||
"${OPTIONS[@]}" \
|
||||
https://gitlab.freedesktop.org/wayland/wayland-protocols.git \
|
||||
1.41
|
||||
fi
|
||||
|
||||
if ! pkgconf --atleast-version 1.8.0 libxkbcommon
|
||||
then
|
||||
./$SCRIPTS_DIR/install-meson-project.sh \
|
||||
"${OPTIONS[@]}" \
|
||||
https://github.com/xkbcommon/libxkbcommon.git \
|
||||
master
|
||||
fi
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPTS_DIR="$(dirname $0)"
|
||||
|
||||
# Location for dependencies to be bundled with the extension
|
||||
DESTDIR="$(realpath $1)"
|
||||
|
||||
# GNOME OS specific setup arguments
|
||||
LIBDIR="lib/$(gcc -print-multiarch)"
|
||||
|
||||
# Install common dependencies
|
||||
./$SCRIPTS_DIR/install-common-dependencies.sh --libdir=$LIBDIR --destdir=$DESTDIR --destdir=/
|
||||
|
||||
# Install below missing dependencies that are exclusive to GNOME OS
|
||||
|
||||
./$SCRIPTS_DIR/install-meson-project.sh \
|
||||
--libdir=$LIBDIR --destdir=$DESTDIR --destdir=/ \
|
||||
https://gitlab.gnome.org/GNOME/zenity.git \
|
||||
master
|
||||
@@ -1,107 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
usage() {
|
||||
cat <<-EOF
|
||||
Usage: $(basename $0) [OPTION…] REPO_URL COMMIT
|
||||
|
||||
Check out and install a meson project
|
||||
|
||||
Options:
|
||||
-Dkey=val Option to pass on to meson
|
||||
--subdir=DIR Build subdirectory instead of whole project
|
||||
--prepare=SCRIPT Script to run before build
|
||||
--libdir=DIR Setup the project with a different libdir
|
||||
--destdir=DIR Install the project to DIR, can be used
|
||||
several times to install to multiple destdirs
|
||||
|
||||
-h, --help Display this help
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
TEMP=$(getopt \
|
||||
--name=$(basename $0) \
|
||||
--options='D:h' \
|
||||
--longoptions='subdir:' \
|
||||
--longoptions='prepare:' \
|
||||
--longoptions='libdir:' \
|
||||
--longoptions='destdir:' \
|
||||
--longoptions='help' \
|
||||
-- "$@")
|
||||
|
||||
eval set -- "$TEMP"
|
||||
unset TEMP
|
||||
|
||||
MESON_OPTIONS=()
|
||||
SUBDIR=.
|
||||
PREPARE=:
|
||||
DESTDIRS=()
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
-D)
|
||||
MESON_OPTIONS+=( -D$2 )
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--subdir)
|
||||
SUBDIR=$2
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--prepare)
|
||||
PREPARE=$2
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--libdir)
|
||||
MESON_OPTIONS+=( --libdir=$2 )
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--destdir)
|
||||
DESTDIRS+=( $2 )
|
||||
shift 2
|
||||
;;
|
||||
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $# -lt 2 ]]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
REPO_URL="$1"
|
||||
COMMIT="$2"
|
||||
|
||||
[[ ${#DESTDIRS[@]} == 0 ]] && DESTDIRS+=( / )
|
||||
|
||||
CHECKOUT_DIR=$(mktemp --directory)
|
||||
trap "rm -rf $CHECKOUT_DIR" EXIT
|
||||
|
||||
git clone --depth 1 "$REPO_URL" -b "$COMMIT" "$CHECKOUT_DIR"
|
||||
|
||||
pushd "$CHECKOUT_DIR/$SUBDIR"
|
||||
sh -c "$PREPARE"
|
||||
meson setup --prefix=/usr _build "${MESON_OPTIONS[@]}"
|
||||
|
||||
# Install it to all specified dest dirs
|
||||
for destdir in "${DESTDIRS[@]}"; do
|
||||
# don't use --destdir when installing to root,
|
||||
# so post-install hooks are run
|
||||
[[ $destdir == / ]] && destdir=
|
||||
sudo meson install -C _build ${destdir:+--destdir=$destdir}
|
||||
done
|
||||
popd
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
OUTFILE=$1
|
||||
NAME=$2
|
||||
MESSAGE=$3
|
||||
|
||||
cat >$OUTFILE <<EOF
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<testsuites tests="1" errors="0" failures="1">
|
||||
<testsuite name="repo-sanity" tests="1" errors="0" failures="1">
|
||||
<testcase name="$NAME" classname="repo-sanity">
|
||||
<failure message="$MESSAGE"/>
|
||||
</testcase>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
EOF
|
||||
|
||||
# Also echo the message in stdout for good measure
|
||||
echo $MESSAGE
|
||||
@@ -1,55 +0,0 @@
|
||||
<!--
|
||||
Please read https://handbook.gnome.org/issues/reporting.html
|
||||
first to ensure that you create a clear and specific issue.
|
||||
-->
|
||||
|
||||
### Affected version
|
||||
|
||||
<!--
|
||||
Provide at least the following information:
|
||||
* Your OS and version
|
||||
* Affected Mutter version
|
||||
* Does this issue appear in XOrg and/or Wayland
|
||||
-->
|
||||
|
||||
### Bug summary
|
||||
|
||||
<!--
|
||||
Provide a short summary of the bug you encountered.
|
||||
-->
|
||||
|
||||
### Steps to reproduce
|
||||
|
||||
<!--
|
||||
1. Step one
|
||||
2. Step two
|
||||
3. ...
|
||||
-->
|
||||
|
||||
### What happened
|
||||
|
||||
<!--
|
||||
What did Mutter do that was unexpected?
|
||||
-->
|
||||
|
||||
### What did you expect to happen
|
||||
|
||||
<!--
|
||||
What did you expect Mutter to do?
|
||||
-->
|
||||
|
||||
### Relevant logs, screenshots, screencasts etc.
|
||||
|
||||
<!--
|
||||
If you have further information, such as technical documentation, logs,
|
||||
screenshots or screencasts related, please provide them here.
|
||||
|
||||
If the bug is a crash, please obtain a stack trace with installed debug
|
||||
symbols (at least for GNOME Shell and Mutter) and attach it to
|
||||
this issue following the instructions on
|
||||
https://handbook.gnome.org/issues/stack-traces.html.
|
||||
-->
|
||||
|
||||
|
||||
<!-- Do not remove the following line. -->
|
||||
/label ~"1. Bug"
|
||||
@@ -1,30 +0,0 @@
|
||||
<!--
|
||||
Please read https://handbook.gnome.org/issues/reporting.html
|
||||
first to ensure that you create a clear and specific issue.
|
||||
-->
|
||||
|
||||
### Feature summary
|
||||
|
||||
<!--
|
||||
Describe what you would like to be able to do with Mutter
|
||||
that you currently cannot do.
|
||||
-->
|
||||
|
||||
### How would you like it to work
|
||||
|
||||
<!--
|
||||
If you can think of a way Mutter might be able to do this,
|
||||
let us know here.
|
||||
-->
|
||||
|
||||
### Relevant links, screenshots, screencasts etc.
|
||||
|
||||
<!--
|
||||
If you have further information, such as technical documentation,
|
||||
code, mockups or a similar feature in another window managers,
|
||||
please provide them here.
|
||||
-->
|
||||
|
||||
|
||||
<!-- Do not remove the following line. -->
|
||||
/label ~"1. Feature"
|
||||
11
Makefile.am
Normal file
11
Makefile.am
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
SUBDIRS = data src po doc
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||
|
||||
DISTCLEANFILES = \
|
||||
intltool-extract \
|
||||
intltool-merge \
|
||||
intltool-update \
|
||||
po/stamp-it \
|
||||
po/.intltool-merge-cache
|
||||
61
README.md
61
README.md
@@ -1,61 +0,0 @@
|
||||
# Mutter
|
||||
|
||||
Mutter is a Wayland display server and X11 window manager and compositor library.
|
||||
|
||||
When used as a Wayland display server, it runs on top of KMS and libinput. It
|
||||
implements the compositor side of the Wayland core protocol as well as various
|
||||
protocol extensions. It also has functionality related to running X11
|
||||
applications using Xwayland.
|
||||
|
||||
When used on top of Xorg it acts as a X11 window manager and compositing manager.
|
||||
|
||||
It contains functionality related to, among other things, window management,
|
||||
window compositing, focus tracking, workspace management, keybindings and
|
||||
monitor configuration.
|
||||
|
||||
Internally it uses a fork of Cogl, a hardware acceleration abstraction library
|
||||
used to simplify usage of OpenGL pipelines, as well as a fork of Clutter, a
|
||||
scene graph and user interface toolkit.
|
||||
|
||||
Mutter is used by, for example, GNOME Shell, the GNOME core user interface, and
|
||||
by Gala, elementary OS's window manager. It can also be run standalone, using
|
||||
the command "mutter", but just running plain mutter is only intended for
|
||||
debugging purposes.
|
||||
|
||||
## Contributing
|
||||
|
||||
To contribute, open merge requests at https://gitlab.gnome.org/GNOME/mutter.
|
||||
|
||||
It can be useful to first look at the
|
||||
[GNOME Handbook](https://handbook.gnome.org/development.html) and the
|
||||
documentation and API references below first.
|
||||
|
||||
## Documentation
|
||||
|
||||
- [Coding style and conventions](doc/coding-style.md)
|
||||
- [Git conventions](doc/git-conventions.md)
|
||||
- [Code overview](doc/code-overview.md)
|
||||
- [Building and Running](doc/building-and-running.md)
|
||||
- [Debugging](doc/debugging.md)
|
||||
- [Monitor configuration](doc/monitor-configuration.md)
|
||||
- [Multi-GPU](doc/multi-gpu.md)
|
||||
|
||||
## API Reference
|
||||
|
||||
- Meta: <https://mutter.gnome.org/meta/>
|
||||
- Clutter: <https://mutter.gnome.org/clutter/>
|
||||
- Cogl: <https://mutter.gnome.org/cogl/>
|
||||
- Mtk: <https://mutter.gnome.org/mtk/>
|
||||
|
||||
## Meetings
|
||||
|
||||
There are [recurring meetings](https://hedgedoc.gnome.org/s/ymP_L5MUs) to
|
||||
discuss development of GNOME Shell, mutter and related components.
|
||||
|
||||
## License
|
||||
|
||||
Mutter is distributed under the terms of the GNU General Public License,
|
||||
version 2 or later. See the [COPYING][license] file for detalis.
|
||||
|
||||
[bug-tracker]: https://gitlab.gnome.org/GNOME/mutter/issues
|
||||
[license]: COPYING
|
||||
21
autogen.sh
Executable file
21
autogen.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
# Run this to generate all the initial makefiles, etc.
|
||||
|
||||
srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
REQUIRED_AUTOMAKE_VERSION=1.11
|
||||
|
||||
(test -f $srcdir/configure.ac \
|
||||
&& test -d $srcdir/src) || {
|
||||
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
|
||||
echo " top-level metacity directory"
|
||||
exit 1
|
||||
}
|
||||
|
||||
which gnome-autogen.sh || {
|
||||
echo "You need to install gnome-common from GNOME Subversion (or from"
|
||||
echo "your distribution's package manager)."
|
||||
exit 1
|
||||
}
|
||||
. gnome-autogen.sh
|
||||
164
check-style.py
164
check-style.py
@@ -1,164 +0,0 @@
|
||||
#!/bin/env python3
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
# Path relative to this script
|
||||
uncrustify_cfg = 'tools/uncrustify.cfg'
|
||||
|
||||
def run_diff(sha):
|
||||
proc = subprocess.run(
|
||||
["git", "diff", "-U0", "--function-context", "--default-prefix", sha, "HEAD"],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
encoding="utf-8",
|
||||
)
|
||||
return proc.stdout.strip().splitlines()
|
||||
|
||||
def find_chunks(diff):
|
||||
file_entry_re = re.compile(r'^\+\+\+ b/(.*)$')
|
||||
diff_chunk_re = re.compile(r'^@@ -\d+,\d+ \+(\d+),(\d+)')
|
||||
file = None
|
||||
chunks = []
|
||||
|
||||
for line in diff:
|
||||
match = file_entry_re.match(line)
|
||||
if match:
|
||||
file = match.group(1)
|
||||
|
||||
match = diff_chunk_re.match(line)
|
||||
if match:
|
||||
start = int(match.group(1))
|
||||
len = int(match.group(2))
|
||||
end = start + len
|
||||
|
||||
if len > 0 and (file.endswith('.c') or file.endswith('.h') or file.endswith('.vala')):
|
||||
chunks.append({ 'file': file, 'start': start, 'end': end })
|
||||
|
||||
return chunks
|
||||
|
||||
def reformat_chunks(chunks, rewrite):
|
||||
# Creates temp file with INDENT-ON/OFF comments
|
||||
def create_temp_file(file, start, end):
|
||||
with open(file) as f:
|
||||
tmp = tempfile.NamedTemporaryFile()
|
||||
if start > 1:
|
||||
tmp.write(b'/** *INDENT-OFF* **/\n')
|
||||
for i, line in enumerate(f, start=1):
|
||||
if i == start - 1:
|
||||
tmp.write(b'/** *INDENT-ON* **/\n')
|
||||
|
||||
tmp.write(bytes(line, 'utf-8'))
|
||||
|
||||
if i == end - 1:
|
||||
tmp.write(b'/** *INDENT-OFF* **/\n')
|
||||
|
||||
tmp.seek(0)
|
||||
|
||||
return tmp
|
||||
|
||||
# Removes uncrustify INDENT-ON/OFF helper comments
|
||||
def remove_indent_comments(output):
|
||||
tmp = tempfile.NamedTemporaryFile()
|
||||
|
||||
for line in output:
|
||||
if line != b'/** *INDENT-OFF* **/\n' and line != b'/** *INDENT-ON* **/\n':
|
||||
tmp.write(line)
|
||||
|
||||
tmp.seek(0)
|
||||
|
||||
return tmp
|
||||
|
||||
changed = None
|
||||
|
||||
for chunk in chunks:
|
||||
# Add INDENT-ON/OFF comments
|
||||
tmp = create_temp_file(chunk['file'], chunk['start'], chunk['end'])
|
||||
|
||||
# uncrustify chunk
|
||||
proc = subprocess.run(
|
||||
["uncrustify", "-c", uncrustify_cfg, "-f", tmp.name],
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
reindented = proc.stdout.splitlines(keepends=True)
|
||||
if proc.returncode != 0:
|
||||
continue
|
||||
|
||||
tmp.close()
|
||||
|
||||
# Remove INDENT-ON/OFF comments
|
||||
formatted = remove_indent_comments(reindented)
|
||||
|
||||
if dry_run is True:
|
||||
# Show changes
|
||||
proc = subprocess.run(
|
||||
["diff", "-up", "--color=always", chunk['file'], formatted.name],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
encoding="utf-8",
|
||||
)
|
||||
diff = proc.stdout
|
||||
if diff != '':
|
||||
output = re.sub('\t', '↦\t', diff)
|
||||
print(output)
|
||||
changed = True
|
||||
else:
|
||||
# Apply changes
|
||||
diff = subprocess.run(
|
||||
["diff", "-up", chunk['file'], formatted.name],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
)
|
||||
patch = subprocess.run(["patch", chunk['file']], input=diff.stdout)
|
||||
|
||||
formatted.close()
|
||||
|
||||
return changed
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description='Check code style. Needs uncrustify installed.')
|
||||
parser.add_argument('--sha', metavar='SHA', type=str,
|
||||
help='SHA for the commit to compare HEAD with')
|
||||
parser.add_argument('--dry-run', '-d', type=bool,
|
||||
action=argparse.BooleanOptionalAction,
|
||||
help='Only print changes to stdout, do not change code')
|
||||
parser.add_argument('--rewrite', '-r', type=bool,
|
||||
action=argparse.BooleanOptionalAction,
|
||||
help='Whether to amend the result to the last commit (e.g. \'git rebase --exec "%(prog)s -r"\')')
|
||||
|
||||
# Change CWD to script location, necessary for always locating the configuration file
|
||||
os.chdir(os.path.dirname(os.path.abspath(sys.argv[0])))
|
||||
|
||||
args = parser.parse_args()
|
||||
sha = args.sha or 'HEAD^'
|
||||
rewrite = args.rewrite
|
||||
dry_run = args.dry_run
|
||||
|
||||
diff = run_diff(sha)
|
||||
chunks = find_chunks(diff)
|
||||
changed = reformat_chunks(chunks, rewrite)
|
||||
|
||||
if dry_run is not True and rewrite is True:
|
||||
proc = subprocess.run(["git", "add", "-p"])
|
||||
if proc.returncode == 0:
|
||||
# Commit the added changes as a squash commit
|
||||
subprocess.run(
|
||||
["git", "commit", "--squash", "HEAD", "-C", "HEAD"],
|
||||
stdout=subprocess.DEVNULL)
|
||||
# Delete the unapplied changes
|
||||
subprocess.run(["git", "reset", "--hard"], stdout=subprocess.DEVNULL)
|
||||
os._exit(0)
|
||||
elif dry_run is True and changed is True:
|
||||
print(f"""
|
||||
Issue the following commands in your local tree to apply the suggested changes:
|
||||
|
||||
$ git rebase {sha} --exec "./check-style.py -r"
|
||||
$ git rebase --autosquash {sha}
|
||||
""")
|
||||
os._exit(-1)
|
||||
|
||||
os._exit(0)
|
||||
@@ -1,35 +0,0 @@
|
||||
/* Clutter.
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atk/atk.h>
|
||||
|
||||
#include "clutter/clutter-macros.h"
|
||||
#include "clutter/clutter-stage.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void _clutter_accessibility_override_atk_util (void);
|
||||
|
||||
gboolean clutter_accessibility_snoop_key_event (ClutterStage *stage,
|
||||
ClutterKeyEvent *key);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,306 +0,0 @@
|
||||
/* Clutter.
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* Based on GailUtil from GAIL
|
||||
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "clutter/clutter-accessibility-private.h"
|
||||
#include "clutter/clutter-context-private.h"
|
||||
#include "clutter/clutter-stage-manager-accessible-private.h"
|
||||
#include "clutter/clutter.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#ifdef HAVE_FONTS
|
||||
#include "clutter/clutter-pango.h"
|
||||
#endif
|
||||
|
||||
#define DEFAULT_PASSWORD_CHAR '*'
|
||||
|
||||
/* This is just a copy of the Gail one, a shared library or place to
|
||||
define it could be a good idea. */
|
||||
typedef struct _KeyEventInfo
|
||||
{
|
||||
AtkKeySnoopFunc listener;
|
||||
gpointer func_data;
|
||||
} KeyEventInfo;
|
||||
|
||||
static AtkObject*root = NULL;
|
||||
static GHashTable *key_listener_list = NULL;
|
||||
|
||||
/* ------------------------------ ATK UTIL METHODS -------------------------- */
|
||||
|
||||
static AtkObject*
|
||||
clutter_accessibility_get_root (void)
|
||||
{
|
||||
ClutterContext *context = _clutter_context_get_default ();
|
||||
ClutterStageManager *stage_manager =
|
||||
clutter_context_get_stage_manager (context);
|
||||
|
||||
if (!root)
|
||||
root = clutter_stage_manager_accessible_new (stage_manager);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
clutter_accessibility_get_toolkit_name (void)
|
||||
{
|
||||
return "clutter";
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
clutter_accessibility_get_toolkit_version (void)
|
||||
{
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
static guint
|
||||
clutter_accessibility_add_key_event_listener (AtkKeySnoopFunc listener,
|
||||
gpointer data)
|
||||
{
|
||||
static guint key = 1;
|
||||
KeyEventInfo *event_info = NULL;
|
||||
|
||||
if (!key_listener_list)
|
||||
key_listener_list = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
|
||||
event_info = g_new (KeyEventInfo, 1);
|
||||
event_info->listener = listener;
|
||||
event_info->func_data = data;
|
||||
|
||||
g_hash_table_insert (key_listener_list, GUINT_TO_POINTER (key++), event_info);
|
||||
/* XXX: we don't check to see if n_listeners > MAXUINT */
|
||||
return key - 1;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_accessibility_remove_key_event_listener (guint remove_listener)
|
||||
{
|
||||
if (!g_hash_table_remove (key_listener_list, GUINT_TO_POINTER (remove_listener))) {
|
||||
g_warning ("Not able to remove listener with id %i", remove_listener);
|
||||
}
|
||||
|
||||
if (g_hash_table_size (key_listener_list) == 0)
|
||||
{
|
||||
g_hash_table_destroy (key_listener_list);
|
||||
key_listener_list = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------ PRIVATE FUNCTIONS ------------------------- */
|
||||
|
||||
static AtkKeyEventStruct *
|
||||
atk_key_event_from_clutter_event_key (ClutterKeyEvent *clutter_event,
|
||||
gunichar password_char)
|
||||
{
|
||||
AtkKeyEventStruct *atk_event = g_new0 (AtkKeyEventStruct, 1);
|
||||
gunichar key_unichar;
|
||||
|
||||
switch (clutter_event_type ((ClutterEvent *) clutter_event))
|
||||
{
|
||||
case CLUTTER_KEY_PRESS:
|
||||
atk_event->type = ATK_KEY_EVENT_PRESS;
|
||||
break;
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
atk_event->type = ATK_KEY_EVENT_RELEASE;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (password_char)
|
||||
atk_event->state = 0;
|
||||
else
|
||||
atk_event->state = clutter_event_get_state ((ClutterEvent *) clutter_event);
|
||||
|
||||
/* We emit the clutter keyval. This is not exactly the one expected
|
||||
by AtkKeyEventStruct, as it expects a Gdk-like event, with the
|
||||
modifiers applied. But to avoid a dependency to gdk, we delegate
|
||||
that on the AT application.
|
||||
More information: Bug 1952 and bug 2072
|
||||
*/
|
||||
if (password_char)
|
||||
atk_event->keyval = clutter_unicode_to_keysym (password_char);
|
||||
else
|
||||
atk_event->keyval = clutter_event_get_key_symbol ((ClutterEvent *) clutter_event);
|
||||
|
||||
/* It is expected to store a key defining string here (ie "Space" in
|
||||
case you press a space). Anyway, there are no function on clutter
|
||||
to obtain that, and we want to avoid a gdk dependency here, so we
|
||||
delegate on the AT application to obtain that string using the
|
||||
rest of the data on the ATK event struct.
|
||||
|
||||
More information: Bug 1952 and 2072
|
||||
*/
|
||||
|
||||
if (password_char)
|
||||
key_unichar = password_char;
|
||||
else
|
||||
key_unichar = clutter_event_get_key_unicode ((ClutterEvent *) clutter_event);
|
||||
|
||||
if (g_unichar_validate (key_unichar) && !g_unichar_iscntrl (key_unichar))
|
||||
{
|
||||
GString *new = NULL;
|
||||
|
||||
new = g_string_new ("");
|
||||
new = g_string_insert_unichar (new, 0, key_unichar);
|
||||
atk_event->string = g_string_free (new, FALSE);
|
||||
}
|
||||
else
|
||||
atk_event->string = NULL;
|
||||
|
||||
atk_event->length = 0;
|
||||
|
||||
/* Computing the hardware keycode from the password-char is
|
||||
difficult. But we are in a password situation. We are already a
|
||||
unichar that it is not the original one. Providing a "almost
|
||||
real" keycode is irrelevant */
|
||||
if (password_char)
|
||||
atk_event->keycode = 0;
|
||||
else
|
||||
atk_event->keycode = clutter_event_get_key_code ((ClutterEvent *) clutter_event);
|
||||
|
||||
atk_event->timestamp = clutter_event_get_time ((ClutterEvent *) clutter_event);
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
|
||||
g_debug ("KeyEvent:\tsym 0x%x\n\t\tmods %x\n\t\tcode %u\n\t\ttime %lx \n\t\tstring %s\n",
|
||||
(unsigned int) atk_event->keyval,
|
||||
(unsigned int) atk_event->state,
|
||||
(unsigned int) atk_event->keycode,
|
||||
(unsigned long int) atk_event->timestamp,
|
||||
atk_event->string);
|
||||
#endif
|
||||
|
||||
return atk_event;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
notify_hf (gpointer key,
|
||||
gpointer value,
|
||||
gpointer data)
|
||||
{
|
||||
KeyEventInfo *info = (KeyEventInfo *) value;
|
||||
AtkKeyEventStruct *key_event = (AtkKeyEventStruct *)data;
|
||||
|
||||
return (*(AtkKeySnoopFunc) info->listener) (key_event, info->func_data) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
insert_hf (gpointer key,
|
||||
gpointer value,
|
||||
gpointer data)
|
||||
{
|
||||
GHashTable *new_table = (GHashTable *) data;
|
||||
g_hash_table_insert (new_table, key, value);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 0 if the key of that event is visible, in other case the password
|
||||
* char
|
||||
*/
|
||||
static gunichar
|
||||
check_key_visibility (ClutterStage *stage)
|
||||
{
|
||||
AtkObject *accessible;
|
||||
ClutterActor *focus;
|
||||
|
||||
focus = clutter_stage_get_key_focus (stage);
|
||||
if (focus == NULL)
|
||||
focus = CLUTTER_ACTOR (stage);
|
||||
accessible = clutter_actor_get_accessible (focus);
|
||||
|
||||
g_return_val_if_fail (accessible != NULL, 0);
|
||||
|
||||
if (atk_object_get_role (accessible) != ATK_ROLE_PASSWORD_TEXT)
|
||||
return 0;
|
||||
|
||||
/* If it is a clutter text, we use his password char. Note that
|
||||
although at Clutter toolkit itself, only ClutterText exposes a
|
||||
password role, nothing prevents on any derived toolkit (like st)
|
||||
to create a new actor that can behave like a password entry. And
|
||||
the key event will still be emitted here. Although in that case
|
||||
we would lose any password char from the derived toolkit, it is
|
||||
still better fill this with a default unichar that the original
|
||||
one */
|
||||
|
||||
#ifdef HAVE_FONTS
|
||||
if (CLUTTER_IS_TEXT (focus))
|
||||
return clutter_text_get_password_char (CLUTTER_TEXT (focus));
|
||||
else
|
||||
#endif
|
||||
return DEFAULT_PASSWORD_CHAR;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_accessibility_snoop_key_event (ClutterStage *stage,
|
||||
ClutterKeyEvent *key)
|
||||
{
|
||||
ClutterEvent *event = (ClutterEvent *) key;
|
||||
AtkKeyEventStruct *key_event = NULL;
|
||||
ClutterEventType event_type;
|
||||
gboolean consumed = FALSE;
|
||||
gunichar password_char = 0;
|
||||
|
||||
event_type = clutter_event_type (event);
|
||||
|
||||
/* filter key events */
|
||||
if ((event_type != CLUTTER_KEY_PRESS) && (event_type != CLUTTER_KEY_RELEASE))
|
||||
return FALSE;
|
||||
|
||||
if (key_listener_list)
|
||||
{
|
||||
GHashTable *new_hash = g_hash_table_new (NULL, NULL);
|
||||
|
||||
g_hash_table_foreach (key_listener_list, insert_hf, new_hash);
|
||||
password_char = check_key_visibility (stage);
|
||||
key_event = atk_key_event_from_clutter_event_key (key, password_char);
|
||||
/* func data is inside the hash table */
|
||||
consumed = g_hash_table_foreach_steal (new_hash, notify_hf, key_event) > 0;
|
||||
g_hash_table_destroy (new_hash);
|
||||
|
||||
g_free (key_event->string);
|
||||
g_free (key_event);
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_accessibility_override_atk_util (void)
|
||||
{
|
||||
AtkUtilClass *atk_class = ATK_UTIL_CLASS (g_type_class_ref (ATK_TYPE_UTIL));
|
||||
|
||||
if (atk_class->get_root)
|
||||
return;
|
||||
|
||||
atk_class->add_key_event_listener = clutter_accessibility_add_key_event_listener;
|
||||
atk_class->remove_key_event_listener = clutter_accessibility_remove_key_event_listener;
|
||||
atk_class->get_root = clutter_accessibility_get_root;
|
||||
atk_class->get_toolkit_name = clutter_accessibility_get_toolkit_name;
|
||||
atk_class->get_toolkit_version = clutter_accessibility_get_toolkit_version;
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2021 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-action.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void clutter_action_set_phase (ClutterAction *action,
|
||||
ClutterEventPhase phase);
|
||||
|
||||
gboolean clutter_action_handle_event (ClutterAction *action,
|
||||
const ClutterEvent *event);
|
||||
|
||||
void clutter_action_sequence_cancelled (ClutterAction *action,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence);
|
||||
|
||||
gboolean clutter_action_register_sequence (ClutterAction *self,
|
||||
const ClutterEvent *event);
|
||||
|
||||
int clutter_action_setup_sequence_relationship (ClutterAction *action_1,
|
||||
ClutterAction *action_2,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterAction:
|
||||
*
|
||||
* Abstract class for event-related logic
|
||||
*
|
||||
* #ClutterAction is an abstract base class for event-related actions that
|
||||
* modify the user interaction of a [class@Actor], just like
|
||||
* [class@Constraint] is an abstract class for modifiers of an actor's
|
||||
* position or size.
|
||||
*
|
||||
* Implementations of #ClutterAction are associated to an actor and can
|
||||
* provide behavioral changes when dealing with user input - for instance
|
||||
* drag and drop capabilities, or scrolling, or panning - by using the
|
||||
* various event-related signals provided by [class@Actor] itself.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-action.h"
|
||||
#include "clutter/clutter-action-private.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
typedef struct _ClutterActionPrivate ClutterActionPrivate;
|
||||
|
||||
struct _ClutterActionPrivate
|
||||
{
|
||||
ClutterEventPhase phase;
|
||||
};
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterAction, clutter_action,
|
||||
CLUTTER_TYPE_ACTOR_META)
|
||||
|
||||
static gboolean
|
||||
clutter_action_handle_event_default (ClutterAction *action,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_action_class_init (ClutterActionClass *klass)
|
||||
{
|
||||
klass->handle_event = clutter_action_handle_event_default;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_action_init (ClutterAction *self)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
clutter_action_set_phase (ClutterAction *action,
|
||||
ClutterEventPhase phase)
|
||||
{
|
||||
ClutterActionPrivate *priv;
|
||||
|
||||
priv = clutter_action_get_instance_private (action);
|
||||
priv->phase = phase;
|
||||
}
|
||||
|
||||
ClutterEventPhase
|
||||
clutter_action_get_phase (ClutterAction *action)
|
||||
{
|
||||
ClutterActionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTION (action), CLUTTER_PHASE_CAPTURE);
|
||||
|
||||
priv = clutter_action_get_instance_private (action);
|
||||
|
||||
return priv->phase;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_action_handle_event (ClutterAction *action,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
gboolean retval = CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
g_object_ref (action);
|
||||
if (clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)))
|
||||
retval = CLUTTER_ACTION_GET_CLASS (action)->handle_event (action, event);
|
||||
g_object_unref (action);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_action_sequence_cancelled (ClutterAction *action,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence)
|
||||
{
|
||||
ClutterActionClass *action_class = CLUTTER_ACTION_GET_CLASS (action);
|
||||
|
||||
if (action_class->sequence_cancelled)
|
||||
action_class->sequence_cancelled (action, device, sequence);
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_action_register_sequence (ClutterAction *self,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
ClutterActionClass *action_class = CLUTTER_ACTION_GET_CLASS (self);
|
||||
|
||||
if (action_class->register_sequence)
|
||||
return action_class->register_sequence (self, event);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
clutter_action_setup_sequence_relationship (ClutterAction *action_1,
|
||||
ClutterAction *action_2,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence)
|
||||
{
|
||||
ClutterActionClass *action_class = CLUTTER_ACTION_GET_CLASS (action_1);
|
||||
|
||||
if (action_class->setup_sequence_relationship)
|
||||
return action_class->setup_sequence_relationship (action_1, action_2, device, sequence);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-actor-meta.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_ACTION (clutter_action_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterAction, clutter_action,
|
||||
CLUTTER, ACTION, ClutterActorMeta);
|
||||
|
||||
/**
|
||||
* ClutterActionClass:
|
||||
*
|
||||
* The ClutterActionClass structure contains only private data
|
||||
*/
|
||||
struct _ClutterActionClass
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterActorMetaClass parent_class;
|
||||
|
||||
gboolean (* handle_event) (ClutterAction *action,
|
||||
const ClutterEvent *event);
|
||||
|
||||
void (* sequence_cancelled) (ClutterAction *action,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence);
|
||||
|
||||
gboolean (* register_sequence) (ClutterAction *self,
|
||||
const ClutterEvent *event);
|
||||
|
||||
int (* setup_sequence_relationship) (ClutterAction *action_1,
|
||||
ClutterAction *action_2,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence);
|
||||
};
|
||||
|
||||
/* ClutterActor API */
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_add_action (ClutterActor *self,
|
||||
ClutterAction *action);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_add_action_with_name (ClutterActor *self,
|
||||
const gchar *name,
|
||||
ClutterAction *action);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_add_action_full (ClutterActor *self,
|
||||
const char *name,
|
||||
ClutterEventPhase phase,
|
||||
ClutterAction *action);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_remove_action (ClutterActor *self,
|
||||
ClutterAction *action);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_remove_action_by_name (ClutterActor *self,
|
||||
const gchar *name);
|
||||
CLUTTER_EXPORT
|
||||
ClutterAction *clutter_actor_get_action (ClutterActor *self,
|
||||
const gchar *name);
|
||||
CLUTTER_EXPORT
|
||||
GList * clutter_actor_get_actions (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_clear_actions (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_has_actions (ClutterActor *self);
|
||||
|
||||
ClutterEventPhase clutter_action_get_phase (ClutterAction *action);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,549 +0,0 @@
|
||||
/* Clutter.
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* Some parts are based on GailWidget from GAIL
|
||||
* GAIL - The GNOME Accessibility Implementation Library
|
||||
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterActorAccessible:
|
||||
*
|
||||
* Implementation of the ATK interfaces for [class@Clutter.Actor]
|
||||
*
|
||||
* #ClutterActorAccessible implements the required ATK interfaces of [class@Clutter.Actor]
|
||||
* exposing the common elements on each actor (position, extents, etc).
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* IMPLEMENTATION NOTES:
|
||||
*
|
||||
* ####
|
||||
*
|
||||
* Focus: clutter hasn't got the focus concept in the same way that GTK, but it
|
||||
* has a key focus managed by the stage. Basically any actor can be focused using
|
||||
* clutter_stage_set_key_focus. So, we will use this approach: all actors are
|
||||
* focusable, and we get the currently focused using clutter_stage_get_key_focus
|
||||
* This affects focus related stateset and some atk_component focus methods (like
|
||||
* grab focus).
|
||||
*
|
||||
* In the same way, we will manage the focus state change management
|
||||
* on the cally-stage object. The reason is avoid missing a focus
|
||||
* state change event if the object is focused just before the
|
||||
* accessibility object being created.
|
||||
*
|
||||
* #AtkAction implementation: on previous releases ClutterActor added
|
||||
* the actions "press", "release" and "click", as at that time some
|
||||
* general-purpose actors like textures were directly used as buttons.
|
||||
*
|
||||
* But now, new toolkits appeared, providing high-level widgets, like
|
||||
* buttons. So in this environment, it doesn't make sense to keep
|
||||
* adding them as default.
|
||||
*
|
||||
* Anyway, current implementation of AtkAction is done at ClutterActorAccessible
|
||||
* providing methods to add and remove actions. This is based on the
|
||||
* one used at gailcell, and proposed as a change on #AtkAction
|
||||
* interface:
|
||||
*
|
||||
* https://bugzilla.gnome.org/show_bug.cgi?id=649804
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <atk/atk.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "clutter/clutter-actor-private.h"
|
||||
#include "clutter/clutter-actor-accessible.h"
|
||||
#include "clutter/clutter-stage.h"
|
||||
|
||||
/* AtkComponent.h */
|
||||
static void clutter_actor_accessible_component_interface_init (AtkComponentIface *iface);
|
||||
|
||||
struct _ClutterActorAccessiblePrivate
|
||||
{
|
||||
GList *children;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (ClutterActorAccessible,
|
||||
clutter_actor_accessible,
|
||||
ATK_TYPE_GOBJECT_ACCESSIBLE,
|
||||
G_ADD_PRIVATE (ClutterActorAccessible)
|
||||
G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT,
|
||||
clutter_actor_accessible_component_interface_init));
|
||||
|
||||
/* ClutterContainer */
|
||||
static gint
|
||||
clutter_actor_accessible_add_actor (ClutterActor *container,
|
||||
ClutterActor *actor,
|
||||
gpointer data)
|
||||
{
|
||||
AtkObject *atk_parent = clutter_actor_get_accessible (container);
|
||||
AtkObject *atk_child = clutter_actor_get_accessible (actor);
|
||||
ClutterActorAccessiblePrivate *priv = clutter_actor_accessible_get_instance_private (CLUTTER_ACTOR_ACCESSIBLE (atk_parent));
|
||||
gint index;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (container), 0);
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0);
|
||||
|
||||
g_object_notify (G_OBJECT (atk_child), "accessible_parent");
|
||||
|
||||
g_list_free (priv->children);
|
||||
|
||||
priv->children = clutter_actor_get_children (CLUTTER_ACTOR (container));
|
||||
|
||||
index = g_list_index (priv->children, actor);
|
||||
g_signal_emit_by_name (atk_parent, "children_changed::add",
|
||||
index, atk_child, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static gint
|
||||
clutter_actor_accessible_remove_actor (ClutterActor *container,
|
||||
ClutterActor *actor,
|
||||
gpointer data)
|
||||
{
|
||||
g_autoptr (AtkObject) atk_child = NULL;
|
||||
AtkPropertyValues values = { NULL };
|
||||
AtkObject *atk_parent = NULL;
|
||||
ClutterActorAccessiblePrivate *priv = NULL;
|
||||
gint index;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (container), 0);
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0);
|
||||
|
||||
atk_parent = clutter_actor_get_accessible (container);
|
||||
atk_child = clutter_actor_get_accessible (actor);
|
||||
|
||||
if (atk_child)
|
||||
{
|
||||
g_assert (ATK_IS_OBJECT (atk_child));
|
||||
g_object_ref (atk_child);
|
||||
|
||||
g_value_init (&values.old_value, G_TYPE_POINTER);
|
||||
g_value_set_pointer (&values.old_value, atk_parent);
|
||||
|
||||
values.property_name = "accessible-parent";
|
||||
|
||||
g_signal_emit_by_name (atk_child,
|
||||
"property_change::accessible-parent", &values, NULL);
|
||||
}
|
||||
|
||||
priv = clutter_actor_accessible_get_instance_private (CLUTTER_ACTOR_ACCESSIBLE (atk_parent));
|
||||
index = g_list_index (priv->children, actor);
|
||||
g_list_free (priv->children);
|
||||
|
||||
priv->children = clutter_actor_get_children (CLUTTER_ACTOR (container));
|
||||
|
||||
if (index >= 0 && index <= g_list_length (priv->children))
|
||||
g_signal_emit_by_name (atk_parent, "children_changed::remove",
|
||||
index, atk_child, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_accessible_initialize (AtkObject *obj,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterActorAccessible *self = NULL;
|
||||
ClutterActorAccessiblePrivate *priv = NULL;
|
||||
ClutterActor *actor = NULL;
|
||||
guint handler_id;
|
||||
|
||||
ATK_OBJECT_CLASS (clutter_actor_accessible_parent_class)->initialize (obj, data);
|
||||
|
||||
self = CLUTTER_ACTOR_ACCESSIBLE (obj);
|
||||
priv = clutter_actor_accessible_get_instance_private (self);
|
||||
actor = CLUTTER_ACTOR (data);
|
||||
|
||||
g_object_set_data (G_OBJECT (obj), "atk-component-layer",
|
||||
GINT_TO_POINTER (ATK_LAYER_MDI));
|
||||
|
||||
priv->children = clutter_actor_get_children (actor);
|
||||
|
||||
/*
|
||||
* We store the handler ids for these signals in case some objects
|
||||
* need to remove these handlers.
|
||||
*/
|
||||
handler_id = g_signal_connect (actor,
|
||||
"child-added",
|
||||
G_CALLBACK (clutter_actor_accessible_add_actor),
|
||||
obj);
|
||||
g_object_set_data (G_OBJECT (obj), "cally-add-handler-id",
|
||||
GUINT_TO_POINTER (handler_id));
|
||||
handler_id = g_signal_connect (actor,
|
||||
"child-removed",
|
||||
G_CALLBACK (clutter_actor_accessible_remove_actor),
|
||||
obj);
|
||||
g_object_set_data (G_OBJECT (obj), "cally-remove-handler-id",
|
||||
GUINT_TO_POINTER (handler_id));
|
||||
|
||||
obj->role = ATK_ROLE_PANEL; /* typically objects implementing ClutterContainer
|
||||
interface would be a panel */
|
||||
}
|
||||
|
||||
/* AtkObject */
|
||||
static const gchar *
|
||||
clutter_actor_accessible_get_name (AtkObject *obj)
|
||||
{
|
||||
const gchar* name = NULL;
|
||||
ClutterActor *actor;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (obj), NULL);
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (obj);
|
||||
if (actor)
|
||||
name = clutter_actor_get_accessible_name (actor);
|
||||
|
||||
if (!name)
|
||||
name = ATK_OBJECT_CLASS (clutter_actor_accessible_parent_class)->get_name (obj);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static AtkRole
|
||||
clutter_actor_accessible_get_role (AtkObject *obj)
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
AtkRole role = ATK_ROLE_INVALID;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (obj), role);
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (obj);
|
||||
|
||||
if (actor == NULL)
|
||||
return role;
|
||||
|
||||
role = actor->accessible_role;
|
||||
if (role == ATK_ROLE_INVALID)
|
||||
role = ATK_OBJECT_CLASS (clutter_actor_accessible_parent_class)->get_role (obj);
|
||||
|
||||
return role;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_accessible_init (ClutterActorAccessible *actor_accessible)
|
||||
{
|
||||
ClutterActorAccessiblePrivate *priv = clutter_actor_accessible_get_instance_private (actor_accessible);
|
||||
priv->children = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_accessible_finalize (GObject *obj)
|
||||
{
|
||||
ClutterActorAccessible *actor_accessible =
|
||||
CLUTTER_ACTOR_ACCESSIBLE (obj);
|
||||
ClutterActorAccessiblePrivate *priv =
|
||||
clutter_actor_accessible_get_instance_private (actor_accessible);
|
||||
|
||||
if (priv->children)
|
||||
{
|
||||
g_list_free (priv->children);
|
||||
priv->children = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (clutter_actor_accessible_parent_class)->finalize (obj);
|
||||
}
|
||||
|
||||
static AtkObject *
|
||||
clutter_actor_accessible_get_parent (AtkObject *obj)
|
||||
{
|
||||
ClutterActor *parent_actor = NULL;
|
||||
AtkObject *parent = NULL;
|
||||
ClutterActor *actor = NULL;
|
||||
ClutterActorAccessible *actor_accessible = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (obj), NULL);
|
||||
|
||||
/* Check if we have and assigned parent */
|
||||
if (obj->accessible_parent)
|
||||
return obj->accessible_parent;
|
||||
|
||||
/* Try to get it from the clutter parent */
|
||||
actor_accessible = CLUTTER_ACTOR_ACCESSIBLE (obj);
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (actor_accessible);
|
||||
if (actor == NULL) /* Object is defunct */
|
||||
return NULL;
|
||||
|
||||
parent_actor = clutter_actor_get_parent (actor);
|
||||
if (parent_actor == NULL)
|
||||
return NULL;
|
||||
|
||||
parent = clutter_actor_get_accessible (parent_actor);
|
||||
|
||||
/* FIXME: I need to review the clutter-embed, to check if in this case I
|
||||
* should get the widget accessible
|
||||
*/
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
static gint
|
||||
clutter_actor_accessible_get_index_in_parent (AtkObject *obj)
|
||||
{
|
||||
ClutterActorAccessible *actor_accessible = NULL;
|
||||
ClutterActor *actor = NULL;
|
||||
ClutterActor *parent_actor = NULL;
|
||||
ClutterActor *iter;
|
||||
gint index = -1;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (obj), -1);
|
||||
|
||||
if (obj->accessible_parent)
|
||||
{
|
||||
gint n_children, i;
|
||||
gboolean found = FALSE;
|
||||
|
||||
n_children = atk_object_get_n_accessible_children (obj->accessible_parent);
|
||||
for (i = 0; i < n_children; i++)
|
||||
{
|
||||
AtkObject *child;
|
||||
|
||||
child = atk_object_ref_accessible_child (obj->accessible_parent, i);
|
||||
if (child == obj)
|
||||
found = TRUE;
|
||||
|
||||
g_object_unref (child);
|
||||
if (found)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
actor_accessible = CLUTTER_ACTOR_ACCESSIBLE (obj);
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (actor_accessible);
|
||||
if (actor == NULL) /* Object is defunct */
|
||||
return -1;
|
||||
|
||||
index = 0;
|
||||
parent_actor = clutter_actor_get_parent (actor);
|
||||
if (parent_actor == NULL)
|
||||
return -1;
|
||||
|
||||
for (iter = clutter_actor_get_first_child (parent_actor);
|
||||
iter != NULL && iter != actor;
|
||||
iter = clutter_actor_get_next_sibling (iter))
|
||||
{
|
||||
index += 1;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static AtkStateSet*
|
||||
clutter_actor_accessible_ref_state_set (AtkObject *obj)
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
g_autoptr (AtkStateSet) parent_state = NULL;
|
||||
AtkStateSet *combined_state, *actor_state = NULL;
|
||||
ClutterActorAccessible *actor_accessible = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (obj), NULL);
|
||||
actor_accessible = CLUTTER_ACTOR_ACCESSIBLE (obj);
|
||||
|
||||
parent_state = ATK_OBJECT_CLASS (clutter_actor_accessible_parent_class)->ref_state_set (obj);
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (actor_accessible);
|
||||
|
||||
if (actor == NULL) /* Object is defunct */
|
||||
{
|
||||
atk_state_set_add_state (parent_state, ATK_STATE_DEFUNCT);
|
||||
combined_state = g_steal_pointer (&parent_state);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor_state = clutter_actor_get_accessible_state (actor);
|
||||
|
||||
if (actor_state)
|
||||
combined_state = atk_state_set_or_sets (parent_state,
|
||||
actor_state);
|
||||
else
|
||||
combined_state = g_steal_pointer (&parent_state);
|
||||
}
|
||||
|
||||
return combined_state;
|
||||
}
|
||||
|
||||
static gint
|
||||
clutter_actor_accessible_get_n_children (AtkObject *obj)
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (obj), 0);
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (obj);
|
||||
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return 0;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0);
|
||||
|
||||
return clutter_actor_get_n_children (actor);
|
||||
}
|
||||
|
||||
static AtkObject*
|
||||
clutter_actor_accessible_ref_child (AtkObject *obj,
|
||||
gint i)
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
ClutterActor *child = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (obj), NULL);
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (obj);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL);
|
||||
|
||||
if (i >= clutter_actor_get_n_children (actor))
|
||||
return NULL;
|
||||
|
||||
child = clutter_actor_get_child_at_index (actor, i);
|
||||
if (child == NULL)
|
||||
return NULL;
|
||||
|
||||
return g_object_ref (clutter_actor_get_accessible (child));
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_accessible_class_init (ClutterActorAccessibleClass *klass)
|
||||
{
|
||||
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
/* GObject */
|
||||
gobject_class->finalize = clutter_actor_accessible_finalize;
|
||||
|
||||
/* AtkObject */
|
||||
class->get_role = clutter_actor_accessible_get_role;
|
||||
class->get_name = clutter_actor_accessible_get_name;
|
||||
class->get_parent = clutter_actor_accessible_get_parent;
|
||||
class->get_index_in_parent = clutter_actor_accessible_get_index_in_parent;
|
||||
class->ref_state_set = clutter_actor_accessible_ref_state_set;
|
||||
class->initialize = clutter_actor_accessible_initialize;
|
||||
class->get_n_children = clutter_actor_accessible_get_n_children;
|
||||
class->ref_child = clutter_actor_accessible_ref_child;
|
||||
}
|
||||
|
||||
/* AtkComponent implementation */
|
||||
static void
|
||||
clutter_actor_accessible_get_extents (AtkComponent *component,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gint *width,
|
||||
gint *height,
|
||||
AtkCoordType coord_type)
|
||||
{
|
||||
ClutterActorAccessible *actor_accessible = NULL;
|
||||
ClutterActor *actor = NULL;
|
||||
gfloat f_width, f_height;
|
||||
graphene_point3d_t verts[4];
|
||||
ClutterActor *stage = NULL;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (component));
|
||||
|
||||
actor_accessible = CLUTTER_ACTOR_ACCESSIBLE (component);
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (actor_accessible);
|
||||
|
||||
if (actor == NULL) /* actor is defunct */
|
||||
return;
|
||||
|
||||
/* If the actor is not placed in any stage, we can't compute the
|
||||
* extents */
|
||||
stage = clutter_actor_get_stage (actor);
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
clutter_actor_get_abs_allocation_vertices (actor, verts);
|
||||
clutter_actor_get_transformed_size (actor, &f_width, &f_height);
|
||||
|
||||
*x = (int) verts[0].x;
|
||||
*y = (int) verts[0].y;
|
||||
*width = (int) ceilf (f_width);
|
||||
*height = (int) ceilf (f_height);
|
||||
}
|
||||
|
||||
static gint
|
||||
clutter_actor_accessible_get_mdi_zorder (AtkComponent *component)
|
||||
{
|
||||
ClutterActorAccessible *actor_accessible = NULL;
|
||||
ClutterActor *actor = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (component), G_MININT);
|
||||
|
||||
actor_accessible = CLUTTER_ACTOR_ACCESSIBLE (component);
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (actor_accessible);
|
||||
|
||||
return (int) clutter_actor_get_z_position (actor);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_actor_accessible_grab_focus (AtkComponent *component)
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
ClutterActor *stage = NULL;
|
||||
ClutterActorAccessible *actor_accessible = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (component), FALSE);
|
||||
|
||||
/* See focus section on implementation notes */
|
||||
actor_accessible = CLUTTER_ACTOR_ACCESSIBLE (component);
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (actor_accessible);
|
||||
stage = clutter_actor_get_stage (actor);
|
||||
|
||||
clutter_stage_set_key_focus (CLUTTER_STAGE (stage),
|
||||
actor);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static double
|
||||
clutter_actor_accessible_get_alpha (AtkComponent *component)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (component), 1.0);
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (component);
|
||||
|
||||
if (!actor)
|
||||
return 1.0;
|
||||
|
||||
return clutter_actor_get_opacity (actor) / 255.0;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_accessible_component_interface_init (AtkComponentIface *iface)
|
||||
{
|
||||
g_return_if_fail (iface != NULL);
|
||||
|
||||
iface->get_extents = clutter_actor_accessible_get_extents;
|
||||
iface->get_mdi_zorder = clutter_actor_accessible_get_mdi_zorder;
|
||||
iface->get_alpha = clutter_actor_accessible_get_alpha;
|
||||
|
||||
/* focus management */
|
||||
iface->grab_focus = clutter_actor_accessible_grab_focus;
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/* Clutter.
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* Some parts are based on GailWidget from GAIL
|
||||
* GAIL - The GNOME Accessibility Implementation Library
|
||||
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <atk/atk.h>
|
||||
|
||||
#include "clutter/clutter-macros.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_ACTOR_ACCESSIBLE (clutter_actor_accessible_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterActorAccessible,
|
||||
clutter_actor_accessible,
|
||||
CLUTTER,
|
||||
ACTOR_ACCESSIBLE,
|
||||
AtkGObjectAccessible)
|
||||
|
||||
typedef struct _ClutterActorAccessible ClutterActorAccessible;
|
||||
typedef struct _ClutterActorAccessibleClass ClutterActorAccessibleClass;
|
||||
typedef struct _ClutterActorAccessiblePrivate ClutterActorAccessiblePrivate;
|
||||
|
||||
struct _ClutterActorAccessibleClass
|
||||
{
|
||||
/*< private >*/
|
||||
AtkGObjectAccessibleClass parent_class;
|
||||
};
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,9 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void _clutter_actor_box_enlarge_for_effects (ClutterActorBox *box);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,606 +0,0 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
#include "clutter/clutter-interval.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#include "clutter/clutter-actor-box-private.h"
|
||||
|
||||
/**
|
||||
* clutter_actor_box_new:
|
||||
* @x_1: X coordinate of the top left point
|
||||
* @y_1: Y coordinate of the top left point
|
||||
* @x_2: X coordinate of the bottom right point
|
||||
* @y_2: Y coordinate of the bottom right point
|
||||
*
|
||||
* Allocates a new [struct@ActorBox] using the passed coordinates
|
||||
* for the top left and bottom right points.
|
||||
*
|
||||
* This function is the logical equivalent of:
|
||||
*
|
||||
* ```c
|
||||
* clutter_actor_box_init (clutter_actor_box_alloc (),
|
||||
* x_1, y_1,
|
||||
* x_2, y_2);
|
||||
* ```
|
||||
*
|
||||
* Return value: (transfer full): the newly allocated #ClutterActorBox.
|
||||
* Use [method@ActorBox.free] to free the resources
|
||||
*/
|
||||
ClutterActorBox *
|
||||
clutter_actor_box_new (gfloat x_1,
|
||||
gfloat y_1,
|
||||
gfloat x_2,
|
||||
gfloat y_2)
|
||||
{
|
||||
return clutter_actor_box_init (clutter_actor_box_alloc (),
|
||||
x_1, y_1,
|
||||
x_2, y_2);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_alloc:
|
||||
*
|
||||
* Allocates a new [struct@ActorBox].
|
||||
*
|
||||
* Return value: (transfer full): the newly allocated #ClutterActorBox.
|
||||
* Use [method@ActorBox.free] to free its resources
|
||||
*/
|
||||
ClutterActorBox *
|
||||
clutter_actor_box_alloc (void)
|
||||
{
|
||||
return g_new0 (ClutterActorBox, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_init:
|
||||
* @box: a #ClutterActorBox
|
||||
* @x_1: X coordinate of the top left point
|
||||
* @y_1: Y coordinate of the top left point
|
||||
* @x_2: X coordinate of the bottom right point
|
||||
* @y_2: Y coordinate of the bottom right point
|
||||
*
|
||||
* Initializes @box with the given coordinates.
|
||||
*
|
||||
* Return value: (transfer none): the initialized #ClutterActorBox
|
||||
*/
|
||||
ClutterActorBox *
|
||||
clutter_actor_box_init (ClutterActorBox *box,
|
||||
gfloat x_1,
|
||||
gfloat y_1,
|
||||
gfloat x_2,
|
||||
gfloat y_2)
|
||||
{
|
||||
g_return_val_if_fail (box != NULL, NULL);
|
||||
|
||||
box->x1 = x_1;
|
||||
box->y1 = y_1;
|
||||
box->x2 = x_2;
|
||||
box->y2 = y_2;
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_init_rect:
|
||||
* @box: a #ClutterActorBox
|
||||
* @x: X coordinate of the origin
|
||||
* @y: Y coordinate of the origin
|
||||
* @width: width of the box
|
||||
* @height: height of the box
|
||||
*
|
||||
* Initializes @box with the given origin and size.
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_init_rect (ClutterActorBox *box,
|
||||
gfloat x,
|
||||
gfloat y,
|
||||
gfloat width,
|
||||
gfloat height)
|
||||
{
|
||||
g_return_if_fail (box != NULL);
|
||||
|
||||
box->x1 = x;
|
||||
box->y1 = y;
|
||||
box->x2 = box->x1 + width;
|
||||
box->y2 = box->y1 + height;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_copy:
|
||||
* @box: a #ClutterActorBox
|
||||
*
|
||||
* Copies @box
|
||||
*
|
||||
* Return value: a newly allocated copy of #ClutterActorBox. Use
|
||||
* [method@ActorBox.free] to free the allocated resources
|
||||
*/
|
||||
ClutterActorBox *
|
||||
clutter_actor_box_copy (const ClutterActorBox *box)
|
||||
{
|
||||
if (G_LIKELY (box != NULL))
|
||||
return g_memdup2 (box, sizeof (ClutterActorBox));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_free:
|
||||
* @box: a #ClutterActorBox
|
||||
*
|
||||
* Frees a #ClutterActorBox allocated using [ctor@ActorBox.new]
|
||||
* or [method@ActorBox.copy].
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_free (ClutterActorBox *box)
|
||||
{
|
||||
if (G_LIKELY (box != NULL))
|
||||
g_free (box);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_equal:
|
||||
* @box_a: a #ClutterActorBox
|
||||
* @box_b: a #ClutterActorBox
|
||||
*
|
||||
* Checks @box_a and @box_b for equality
|
||||
*
|
||||
* Return value: %TRUE if the passed #ClutterActorBox are equal
|
||||
*/
|
||||
gboolean
|
||||
clutter_actor_box_equal (const ClutterActorBox *box_a,
|
||||
const ClutterActorBox *box_b)
|
||||
{
|
||||
g_return_val_if_fail (box_a != NULL && box_b != NULL, FALSE);
|
||||
|
||||
if (box_a == box_b)
|
||||
return TRUE;
|
||||
|
||||
return box_a->x1 == box_b->x1 && box_a->y1 == box_b->y1 &&
|
||||
box_a->x2 == box_b->x2 && box_a->y2 == box_b->y2;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_get_x:
|
||||
* @box: a #ClutterActorBox
|
||||
*
|
||||
* Retrieves the X coordinate of the origin of @box
|
||||
*
|
||||
* Return value: the X coordinate of the origin
|
||||
*/
|
||||
gfloat
|
||||
clutter_actor_box_get_x (const ClutterActorBox *box)
|
||||
{
|
||||
g_return_val_if_fail (box != NULL, 0.);
|
||||
|
||||
return box->x1;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_get_y:
|
||||
* @box: a #ClutterActorBox
|
||||
*
|
||||
* Retrieves the Y coordinate of the origin of @box
|
||||
*
|
||||
* Return value: the Y coordinate of the origin
|
||||
*/
|
||||
gfloat
|
||||
clutter_actor_box_get_y (const ClutterActorBox *box)
|
||||
{
|
||||
g_return_val_if_fail (box != NULL, 0.);
|
||||
|
||||
return box->y1;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_get_width:
|
||||
* @box: a #ClutterActorBox
|
||||
*
|
||||
* Retrieves the width of the @box
|
||||
*
|
||||
* Return value: the width of the box
|
||||
*/
|
||||
gfloat
|
||||
clutter_actor_box_get_width (const ClutterActorBox *box)
|
||||
{
|
||||
g_return_val_if_fail (box != NULL, 0.);
|
||||
|
||||
return box->x2 - box->x1;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_get_height:
|
||||
* @box: a #ClutterActorBox
|
||||
*
|
||||
* Retrieves the height of the @box
|
||||
*
|
||||
* Return value: the height of the box
|
||||
*/
|
||||
gfloat
|
||||
clutter_actor_box_get_height (const ClutterActorBox *box)
|
||||
{
|
||||
g_return_val_if_fail (box != NULL, 0.);
|
||||
|
||||
return box->y2 - box->y1;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_get_origin:
|
||||
* @box: a #ClutterActorBox
|
||||
* @x: (out) (allow-none): return location for the X coordinate, or %NULL
|
||||
* @y: (out) (allow-none): return location for the Y coordinate, or %NULL
|
||||
*
|
||||
* Retrieves the origin of @box
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_get_origin (const ClutterActorBox *box,
|
||||
gfloat *x,
|
||||
gfloat *y)
|
||||
{
|
||||
g_return_if_fail (box != NULL);
|
||||
|
||||
if (x)
|
||||
*x = box->x1;
|
||||
|
||||
if (y)
|
||||
*y = box->y1;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_get_size:
|
||||
* @box: a #ClutterActorBox
|
||||
* @width: (out) (allow-none): return location for the width, or %NULL
|
||||
* @height: (out) (allow-none): return location for the height, or %NULL
|
||||
*
|
||||
* Retrieves the size of @box
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_get_size (const ClutterActorBox *box,
|
||||
gfloat *width,
|
||||
gfloat *height)
|
||||
{
|
||||
g_return_if_fail (box != NULL);
|
||||
|
||||
if (width)
|
||||
*width = box->x2 - box->x1;
|
||||
|
||||
if (height)
|
||||
*height = box->y2 - box->y1;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_get_area:
|
||||
* @box: a #ClutterActorBox
|
||||
*
|
||||
* Retrieves the area of @box
|
||||
*
|
||||
* Return value: the area of a #ClutterActorBox, in pixels
|
||||
*/
|
||||
gfloat
|
||||
clutter_actor_box_get_area (const ClutterActorBox *box)
|
||||
{
|
||||
g_return_val_if_fail (box != NULL, 0.);
|
||||
|
||||
return (box->x2 - box->x1) * (box->y2 - box->y1);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_contains:
|
||||
* @box: a #ClutterActorBox
|
||||
* @x: X coordinate of the point
|
||||
* @y: Y coordinate of the point
|
||||
*
|
||||
* Checks whether a point with @x, @y coordinates is contained
|
||||
* within @box
|
||||
*
|
||||
* Return value: %TRUE if the point is contained by the #ClutterActorBox
|
||||
*/
|
||||
gboolean
|
||||
clutter_actor_box_contains (const ClutterActorBox *box,
|
||||
gfloat x,
|
||||
gfloat y)
|
||||
{
|
||||
g_return_val_if_fail (box != NULL, FALSE);
|
||||
|
||||
return (x > box->x1 && x < box->x2) &&
|
||||
(y > box->y1 && y < box->y2);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_from_vertices:
|
||||
* @box: a #ClutterActorBox
|
||||
* @verts: (array fixed-size=4): array of four #graphene_point3d_t
|
||||
*
|
||||
* Calculates the bounding box represented by the four vertices; for details
|
||||
* of the vertex array see [method@Actor.get_abs_allocation_vertices].
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_from_vertices (ClutterActorBox *box,
|
||||
const graphene_point3d_t verts[])
|
||||
{
|
||||
gfloat x_1, x_2, y_1, y_2;
|
||||
|
||||
g_return_if_fail (box != NULL);
|
||||
g_return_if_fail (verts != NULL);
|
||||
|
||||
/* 4-way min/max */
|
||||
x_1 = verts[0].x;
|
||||
y_1 = verts[0].y;
|
||||
|
||||
if (verts[1].x < x_1)
|
||||
x_1 = verts[1].x;
|
||||
|
||||
if (verts[2].x < x_1)
|
||||
x_1 = verts[2].x;
|
||||
|
||||
if (verts[3].x < x_1)
|
||||
x_1 = verts[3].x;
|
||||
|
||||
if (verts[1].y < y_1)
|
||||
y_1 = verts[1].y;
|
||||
|
||||
if (verts[2].y < y_1)
|
||||
y_1 = verts[2].y;
|
||||
|
||||
if (verts[3].y < y_1)
|
||||
y_1 = verts[3].y;
|
||||
|
||||
x_2 = verts[0].x;
|
||||
y_2 = verts[0].y;
|
||||
|
||||
if (verts[1].x > x_2)
|
||||
x_2 = verts[1].x;
|
||||
|
||||
if (verts[2].x > x_2)
|
||||
x_2 = verts[2].x;
|
||||
|
||||
if (verts[3].x > x_2)
|
||||
x_2 = verts[3].x;
|
||||
|
||||
if (verts[1].y > y_2)
|
||||
y_2 = verts[1].y;
|
||||
|
||||
if (verts[2].y > y_2)
|
||||
y_2 = verts[2].y;
|
||||
|
||||
if (verts[3].y > y_2)
|
||||
y_2 = verts[3].y;
|
||||
|
||||
box->x1 = x_1;
|
||||
box->x2 = x_2;
|
||||
box->y1 = y_1;
|
||||
box->y2 = y_2;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_interpolate:
|
||||
* @initial: the initial #ClutterActorBox
|
||||
* @final: the final #ClutterActorBox
|
||||
* @progress: the interpolation progress
|
||||
* @result: (out): return location for the interpolation
|
||||
*
|
||||
* Interpolates between @initial and @final `ClutterActorBox`es
|
||||
* using @progress
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_interpolate (const ClutterActorBox *initial,
|
||||
const ClutterActorBox *final,
|
||||
gdouble progress,
|
||||
ClutterActorBox *result)
|
||||
{
|
||||
g_return_if_fail (initial != NULL);
|
||||
g_return_if_fail (final != NULL);
|
||||
g_return_if_fail (result != NULL);
|
||||
|
||||
result->x1 = (float) (initial->x1 + (final->x1 - initial->x1) * progress);
|
||||
result->y1 = (float) (initial->y1 + (final->y1 - initial->y1) * progress);
|
||||
result->x2 = (float) (initial->x2 + (final->x2 - initial->x2) * progress);
|
||||
result->y2 = (float) (initial->y2 + (final->y2 - initial->y2) * progress);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_clamp_to_pixel:
|
||||
* @box: (inout): the #ClutterActorBox to clamp
|
||||
*
|
||||
* Clamps the components of @box to the nearest integer
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_clamp_to_pixel (ClutterActorBox *box)
|
||||
{
|
||||
g_return_if_fail (box != NULL);
|
||||
|
||||
box->x1 = floorf (box->x1);
|
||||
box->y1 = floorf (box->y1);
|
||||
box->x2 = ceilf (box->x2);
|
||||
box->y2 = ceilf (box->y2);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_union:
|
||||
* @a: (in): the first #ClutterActorBox
|
||||
* @b: (in): the second #ClutterActorBox
|
||||
* @result: (out): the #ClutterActorBox representing a union
|
||||
* of @a and @b
|
||||
*
|
||||
* Unions the two boxes @a and @b and stores the result in @result.
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_union (const ClutterActorBox *a,
|
||||
const ClutterActorBox *b,
|
||||
ClutterActorBox *result)
|
||||
{
|
||||
g_return_if_fail (a != NULL);
|
||||
g_return_if_fail (b != NULL);
|
||||
g_return_if_fail (result != NULL);
|
||||
|
||||
result->x1 = MIN (a->x1, b->x1);
|
||||
result->y1 = MIN (a->y1, b->y1);
|
||||
|
||||
result->x2 = MAX (a->x2, b->x2);
|
||||
result->y2 = MAX (a->y2, b->y2);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_actor_box_progress (const GValue *a,
|
||||
const GValue *b,
|
||||
gdouble factor,
|
||||
GValue *retval)
|
||||
{
|
||||
ClutterActorBox res = { 0, };
|
||||
|
||||
clutter_actor_box_interpolate (g_value_get_boxed (a),
|
||||
g_value_get_boxed (b),
|
||||
factor,
|
||||
&res);
|
||||
|
||||
g_value_set_boxed (retval, &res);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_set_origin:
|
||||
* @box: a #ClutterActorBox
|
||||
* @x: the X coordinate of the new origin
|
||||
* @y: the Y coordinate of the new origin
|
||||
*
|
||||
* Changes the origin of @box, maintaining the size of the #ClutterActorBox.
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_set_origin (ClutterActorBox *box,
|
||||
gfloat x,
|
||||
gfloat y)
|
||||
{
|
||||
gfloat width, height;
|
||||
|
||||
g_return_if_fail (box != NULL);
|
||||
|
||||
width = box->x2 - box->x1;
|
||||
height = box->y2 - box->y1;
|
||||
|
||||
clutter_actor_box_init_rect (box, x, y, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_set_size:
|
||||
* @box: a #ClutterActorBox
|
||||
* @width: the new width
|
||||
* @height: the new height
|
||||
*
|
||||
* Sets the size of @box, maintaining the origin of the #ClutterActorBox.
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_set_size (ClutterActorBox *box,
|
||||
gfloat width,
|
||||
gfloat height)
|
||||
{
|
||||
g_return_if_fail (box != NULL);
|
||||
|
||||
box->x2 = box->x1 + width;
|
||||
box->y2 = box->y1 + height;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_actor_box_enlarge_for_effects (ClutterActorBox *box)
|
||||
{
|
||||
float width, height;
|
||||
|
||||
if (clutter_actor_box_get_area (box) == 0.0)
|
||||
return;
|
||||
|
||||
/* The aim here is that for a given rectangle defined with floating point
|
||||
* coordinates we want to determine a stable quantized size in pixels
|
||||
* that doesn't vary due to the original box's sub-pixel position.
|
||||
*
|
||||
* The reason this is important is because effects will use this
|
||||
* API to determine the size of offscreen framebuffers and so for
|
||||
* a fixed-size object that may be animated across the screen we
|
||||
* want to make sure that the stage paint-box has an equally stable
|
||||
* size so that effects aren't made to continuously re-allocate
|
||||
* a corresponding fbo.
|
||||
*
|
||||
* The other thing we consider is that the calculation of this box is
|
||||
* subject to floating point precision issues that might be slightly
|
||||
* different to the precision issues involved with actually painting the
|
||||
* actor, which might result in painting slightly leaking outside the
|
||||
* user's calculated paint-volume. For this we simply aim to pad out the
|
||||
* paint-volume by at least half a pixel all the way around.
|
||||
*/
|
||||
width = box->x2 - box->x1;
|
||||
height = box->y2 - box->y1;
|
||||
width = CLUTTER_NEARBYINT (width);
|
||||
height = CLUTTER_NEARBYINT (height);
|
||||
/* XXX: NB the width/height may now be up to 0.5px too small so we
|
||||
* must also pad by 0.25px all around to account for this. In total we
|
||||
* must padd by at least 0.75px around all sides. */
|
||||
|
||||
/* XXX: The furthest that we can overshoot the bottom right corner by
|
||||
* here is 1.75px in total if you consider that the 0.75 padding could
|
||||
* just cross an integer boundary and so ceil will effectively add 1.
|
||||
*/
|
||||
box->x2 = ceilf (box->x2 + 0.75f);
|
||||
box->y2 = ceilf (box->y2 + 0.75f);
|
||||
|
||||
/* Now we redefine the top-left relative to the bottom right based on the
|
||||
* rounded width/height determined above + a constant so that the overall
|
||||
* size of the box will be stable and not dependent on the box's
|
||||
* position.
|
||||
*
|
||||
* Adding 3px to the width/height will ensure we cover the maximum of
|
||||
* 1.75px padding on the bottom/right and still ensure we have > 0.75px
|
||||
* padding on the top/left.
|
||||
*/
|
||||
box->x1 = box->x2 - width - 3;
|
||||
box->y1 = box->y2 - height - 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_scale:
|
||||
* @box: a #ClutterActorBox
|
||||
* @scale: scale factor for resizing this box
|
||||
*
|
||||
* Rescale the @box by provided @scale factor.
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_scale (ClutterActorBox *box,
|
||||
gfloat scale)
|
||||
{
|
||||
g_return_if_fail (box != NULL);
|
||||
|
||||
box->x1 *= scale;
|
||||
box->x2 *= scale;
|
||||
box->y1 *= scale;
|
||||
box->y2 *= scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_is_initialized:
|
||||
* @box: a #ClutterActorBox
|
||||
*
|
||||
* Checks if @box has been initialized, a #ClutterActorBox is uninitialized
|
||||
* if it has a size of -1 at an origin of 0, 0.
|
||||
*
|
||||
* Returns: %TRUE if the box is uninitialized, %FALSE if it isn't
|
||||
*/
|
||||
gboolean
|
||||
clutter_actor_box_is_initialized (ClutterActorBox *box)
|
||||
{
|
||||
gboolean x1_uninitialized, x2_uninitialized;
|
||||
gboolean y1_uninitialized, y2_uninitialized;
|
||||
|
||||
g_return_val_if_fail (box != NULL, TRUE);
|
||||
|
||||
x1_uninitialized = isinf (box->x1);
|
||||
x2_uninitialized = isinf (box->x2) && signbit (box->x2);
|
||||
y1_uninitialized = isinf (box->y1);
|
||||
y2_uninitialized = isinf (box->y2) && signbit (box->y2);
|
||||
|
||||
return !x1_uninitialized || !x2_uninitialized ||
|
||||
!y1_uninitialized || !y2_uninitialized;
|
||||
}
|
||||
|
||||
G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterActorBox, clutter_actor_box,
|
||||
clutter_actor_box_copy,
|
||||
clutter_actor_box_free,
|
||||
CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_actor_box_progress));
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "clutter/clutter-actor-meta.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_META_GROUP (_clutter_meta_group_get_type ())
|
||||
|
||||
|
||||
struct _ClutterMetaGroup
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
ClutterActor *actor;
|
||||
|
||||
GList *meta;
|
||||
};
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ClutterMetaGroup,
|
||||
_clutter_meta_group,
|
||||
CLUTTER, META_GROUP,
|
||||
GObject)
|
||||
|
||||
/* Each actor meta has a priority with zero as a default. A higher
|
||||
number means higher priority. Higher priority metas stay at the
|
||||
beginning of the list. The priority can be negative to give lower
|
||||
priority than the default. */
|
||||
|
||||
#define CLUTTER_ACTOR_META_PRIORITY_DEFAULT 0
|
||||
|
||||
/* Any value greater than this is considered an 'internal' priority
|
||||
and if we expose the priority property publicly then an application
|
||||
would not be able to use these values. */
|
||||
|
||||
#define CLUTTER_ACTOR_META_PRIORITY_INTERNAL_HIGH (G_MAXINT / 2)
|
||||
#define CLUTTER_ACTOR_META_PRIORITY_INTERNAL_LOW (G_MININT / 2)
|
||||
|
||||
void _clutter_meta_group_add_meta (ClutterMetaGroup *group,
|
||||
ClutterActorMeta *meta);
|
||||
void _clutter_meta_group_remove_meta (ClutterMetaGroup *group,
|
||||
ClutterActorMeta *meta);
|
||||
const GList * _clutter_meta_group_peek_metas (ClutterMetaGroup *group);
|
||||
void _clutter_meta_group_clear_metas (ClutterMetaGroup *group);
|
||||
ClutterActorMeta * _clutter_meta_group_get_meta (ClutterMetaGroup *group,
|
||||
const gchar *name);
|
||||
|
||||
gboolean _clutter_meta_group_has_metas_no_internal (ClutterMetaGroup *group);
|
||||
|
||||
GList * _clutter_meta_group_get_metas_no_internal (ClutterMetaGroup *group);
|
||||
void _clutter_meta_group_clear_metas_no_internal (ClutterMetaGroup *group);
|
||||
|
||||
/* ActorMeta */
|
||||
const gchar * _clutter_actor_meta_get_debug_name (ClutterActorMeta *meta);
|
||||
|
||||
void _clutter_actor_meta_set_priority (ClutterActorMeta *meta,
|
||||
gint priority);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,702 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterActorMeta:
|
||||
*
|
||||
* Base class of actor modifiers
|
||||
*
|
||||
* #ClutterActorMeta is an abstract class providing a common API for
|
||||
* modifiers of [class@Actor] behaviour, appearance or layout.
|
||||
*
|
||||
* A #ClutterActorMeta can only be owned by a single [class@Actor] at
|
||||
* any time.
|
||||
*
|
||||
* Every sub-class of #ClutterActorMeta should check if the
|
||||
* [property@ActorMeta:enabled] property is set to %TRUE before applying
|
||||
* any kind of modification.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-actor-meta-private.h"
|
||||
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
struct _ClutterActorMetaPrivate
|
||||
{
|
||||
ClutterActor *actor;
|
||||
gulong destroy_id;
|
||||
|
||||
gchar *name;
|
||||
|
||||
guint is_enabled : 1;
|
||||
|
||||
gint priority;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_ACTOR,
|
||||
PROP_NAME,
|
||||
PROP_ENABLED,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterActorMeta,
|
||||
clutter_actor_meta,
|
||||
G_TYPE_INITIALLY_UNOWNED)
|
||||
|
||||
static void
|
||||
on_actor_destroy (ClutterActor *actor,
|
||||
ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
priv->actor = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_meta_real_set_actor (ClutterActorMeta *meta,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
g_warn_if_fail (!priv->actor ||
|
||||
!CLUTTER_ACTOR_IN_PAINT (priv->actor));
|
||||
g_warn_if_fail (!actor || !CLUTTER_ACTOR_IN_PAINT (actor));
|
||||
|
||||
if (priv->actor == actor)
|
||||
return;
|
||||
|
||||
g_clear_signal_handler (&priv->destroy_id, priv->actor);
|
||||
|
||||
priv->actor = actor;
|
||||
|
||||
if (priv->actor != NULL)
|
||||
priv->destroy_id = g_signal_connect (priv->actor, "destroy",
|
||||
G_CALLBACK (on_actor_destroy),
|
||||
meta);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ACTOR]);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_meta_real_set_enabled (ClutterActorMeta *meta,
|
||||
gboolean is_enabled)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
g_warn_if_fail (!priv->actor ||
|
||||
!CLUTTER_ACTOR_IN_PAINT (priv->actor));
|
||||
|
||||
priv->is_enabled = is_enabled;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ENABLED]);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_meta_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
clutter_actor_meta_set_name (meta, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_ENABLED:
|
||||
clutter_actor_meta_set_enabled (meta, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_meta_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (CLUTTER_ACTOR_META (gobject));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ACTOR:
|
||||
g_value_set_object (value, priv->actor);
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, priv->name);
|
||||
break;
|
||||
|
||||
case PROP_ENABLED:
|
||||
g_value_set_boolean (value, priv->is_enabled);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_meta_finalize (GObject *gobject)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (CLUTTER_ACTOR_META (gobject));
|
||||
|
||||
if (priv->actor != NULL)
|
||||
g_clear_signal_handler (&priv->destroy_id, priv->actor);
|
||||
|
||||
g_free (priv->name);
|
||||
|
||||
G_OBJECT_CLASS (clutter_actor_meta_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_actor_meta_class_init (ClutterActorMetaClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
klass->set_actor = clutter_actor_meta_real_set_actor;
|
||||
klass->set_enabled = clutter_actor_meta_real_set_enabled;
|
||||
|
||||
/**
|
||||
* ClutterActorMeta:actor:
|
||||
*
|
||||
* The #ClutterActor attached to the #ClutterActorMeta instance
|
||||
*/
|
||||
obj_props[PROP_ACTOR] =
|
||||
g_param_spec_object ("actor", NULL, NULL,
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* ClutterActorMeta:name:
|
||||
*
|
||||
* The unique name to access the #ClutterActorMeta
|
||||
*/
|
||||
obj_props[PROP_NAME] =
|
||||
g_param_spec_string ("name", NULL, NULL,
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterActorMeta:enabled:
|
||||
*
|
||||
* Whether or not the #ClutterActorMeta is enabled
|
||||
*/
|
||||
obj_props[PROP_ENABLED] =
|
||||
g_param_spec_boolean ("enabled", NULL, NULL,
|
||||
TRUE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
gobject_class->finalize = clutter_actor_meta_finalize;
|
||||
gobject_class->set_property = clutter_actor_meta_set_property;
|
||||
gobject_class->get_property = clutter_actor_meta_get_property;
|
||||
g_object_class_install_properties (gobject_class,
|
||||
PROP_LAST,
|
||||
obj_props);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_actor_meta_init (ClutterActorMeta *self)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (self);
|
||||
|
||||
priv->is_enabled = TRUE;
|
||||
priv->priority = CLUTTER_ACTOR_META_PRIORITY_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_meta_set_name:
|
||||
* @meta: a #ClutterActorMeta
|
||||
* @name: the name of @meta
|
||||
*
|
||||
* Sets the name of @meta
|
||||
*
|
||||
* The name can be used to identify the #ClutterActorMeta instance
|
||||
*/
|
||||
void
|
||||
clutter_actor_meta_set_name (ClutterActorMeta *meta,
|
||||
const gchar *name)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
|
||||
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
if (g_strcmp0 (priv->name, name) == 0)
|
||||
return;
|
||||
|
||||
g_free (priv->name);
|
||||
priv->name = g_strdup (name);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_NAME]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_meta_get_name:
|
||||
* @meta: a #ClutterActorMeta
|
||||
*
|
||||
* Retrieves the name set using [method@ActorMeta.set_name]
|
||||
*
|
||||
* Return value: (transfer none): the name of the #ClutterActorMeta
|
||||
* instance, or %NULL if none was set. The returned string is owned
|
||||
* by the #ClutterActorMeta instance and it should not be modified
|
||||
* or freed
|
||||
*/
|
||||
const gchar *
|
||||
clutter_actor_meta_get_name (ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
|
||||
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
return priv->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_meta_set_enabled:
|
||||
* @meta: a #ClutterActorMeta
|
||||
* @is_enabled: whether @meta is enabled
|
||||
*
|
||||
* Sets whether @meta should be enabled or not
|
||||
*/
|
||||
void
|
||||
clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
|
||||
gboolean is_enabled)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
|
||||
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
is_enabled = !!is_enabled;
|
||||
|
||||
if (priv->is_enabled == is_enabled)
|
||||
return;
|
||||
|
||||
CLUTTER_ACTOR_META_GET_CLASS (meta)->set_enabled (meta, is_enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_meta_get_enabled:
|
||||
* @meta: a #ClutterActorMeta
|
||||
*
|
||||
* Retrieves whether @meta is enabled
|
||||
*
|
||||
* Return value: %TRUE if the #ClutterActorMeta instance is enabled
|
||||
*/
|
||||
gboolean
|
||||
clutter_actor_meta_get_enabled (ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), FALSE);
|
||||
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
return priv->is_enabled;
|
||||
}
|
||||
|
||||
/*
|
||||
* _clutter_actor_meta_set_actor
|
||||
* @meta: a #ClutterActorMeta
|
||||
* @actor: a #ClutterActor or %NULL
|
||||
*
|
||||
* Sets or unsets a back pointer to the #ClutterActor that owns
|
||||
* the @meta
|
||||
*/
|
||||
static void
|
||||
_clutter_actor_meta_set_actor (ClutterActorMeta *meta,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
|
||||
g_return_if_fail (actor == NULL || CLUTTER_IS_ACTOR (actor));
|
||||
|
||||
CLUTTER_ACTOR_META_GET_CLASS (meta)->set_actor (meta, actor);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_meta_get_actor:
|
||||
* @meta: a #ClutterActorMeta
|
||||
*
|
||||
* Retrieves a pointer to the [class@Actor] that owns @meta
|
||||
*
|
||||
* Return value: (transfer none): a pointer to a #ClutterActor or %NULL
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_actor_meta_get_actor (ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
|
||||
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
return priv->actor;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_actor_meta_set_priority (ClutterActorMeta *meta,
|
||||
gint priority)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
|
||||
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
/* This property shouldn't be modified after the actor meta is in
|
||||
use because ClutterMetaGroup doesn't resort the list when it
|
||||
changes. If we made the priority public then we could either make
|
||||
the priority a construct-only property or listen for
|
||||
notifications on the property from the ClutterMetaGroup and
|
||||
resort. */
|
||||
g_return_if_fail (priv->actor == NULL);
|
||||
|
||||
priv->priority = priority;
|
||||
}
|
||||
|
||||
static gint
|
||||
_clutter_actor_meta_get_priority (ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), 0);
|
||||
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
return priv->priority;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_clutter_actor_meta_is_internal (ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
gint priority = priv->priority;
|
||||
|
||||
return (priority <= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_LOW ||
|
||||
priority >= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_HIGH);
|
||||
}
|
||||
|
||||
/*
|
||||
* ClutterMetaGroup: a collection of ClutterActorMeta instances
|
||||
*/
|
||||
|
||||
G_DEFINE_FINAL_TYPE (ClutterMetaGroup, _clutter_meta_group, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
_clutter_meta_group_dispose (GObject *gobject)
|
||||
{
|
||||
_clutter_meta_group_clear_metas (CLUTTER_META_GROUP (gobject));
|
||||
|
||||
G_OBJECT_CLASS (_clutter_meta_group_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
_clutter_meta_group_class_init (ClutterMetaGroupClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->dispose = _clutter_meta_group_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
_clutter_meta_group_init (ClutterMetaGroup *self)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* _clutter_meta_group_add_meta:
|
||||
* @group: a #ClutterMetaGroup
|
||||
* @meta: a #ClutterActorMeta to add
|
||||
*
|
||||
* Adds @meta to @group
|
||||
*
|
||||
* This function will remove the floating reference of @meta or, if the
|
||||
* floating reference has already been sunk, add a reference to it
|
||||
*/
|
||||
void
|
||||
_clutter_meta_group_add_meta (ClutterMetaGroup *group,
|
||||
ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
GList *prev = NULL, *l;
|
||||
|
||||
if (priv->actor != NULL)
|
||||
{
|
||||
g_warning ("The meta of type '%s' with name '%s' is "
|
||||
"already attached to actor '%s'",
|
||||
G_OBJECT_TYPE_NAME (meta),
|
||||
priv->name != NULL
|
||||
? priv->name
|
||||
: "<unknown>",
|
||||
clutter_actor_get_name (priv->actor) != NULL
|
||||
? clutter_actor_get_name (priv->actor)
|
||||
: G_OBJECT_TYPE_NAME (priv->actor));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find a meta that has lower priority and insert before that */
|
||||
for (l = group->meta; l; l = l->next)
|
||||
if (_clutter_actor_meta_get_priority (l->data) <
|
||||
_clutter_actor_meta_get_priority (meta))
|
||||
break;
|
||||
else
|
||||
prev = l;
|
||||
|
||||
if (prev == NULL)
|
||||
group->meta = g_list_prepend (group->meta, meta);
|
||||
else
|
||||
{
|
||||
prev->next = g_list_prepend (prev->next, meta);
|
||||
prev->next->prev = prev;
|
||||
}
|
||||
|
||||
g_object_ref_sink (meta);
|
||||
|
||||
_clutter_actor_meta_set_actor (meta, group->actor);
|
||||
}
|
||||
|
||||
/*
|
||||
* _clutter_meta_group_remove_meta:
|
||||
* @group: a #ClutterMetaGroup
|
||||
* @meta: a #ClutterActorMeta to remove
|
||||
*
|
||||
* Removes @meta from @group and releases the reference being held on it
|
||||
*/
|
||||
void
|
||||
_clutter_meta_group_remove_meta (ClutterMetaGroup *group,
|
||||
ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
if (priv->actor != group->actor)
|
||||
{
|
||||
g_warning ("The meta of type '%s' with name '%s' is not "
|
||||
"attached to the actor '%s'",
|
||||
G_OBJECT_TYPE_NAME (meta),
|
||||
priv->name != NULL
|
||||
? priv->name
|
||||
: "<unknown>",
|
||||
clutter_actor_get_name (group->actor) != NULL
|
||||
? clutter_actor_get_name (group->actor)
|
||||
: G_OBJECT_TYPE_NAME (group->actor));
|
||||
return;
|
||||
}
|
||||
|
||||
_clutter_actor_meta_set_actor (meta, NULL);
|
||||
|
||||
group->meta = g_list_remove (group->meta, meta);
|
||||
g_object_unref (meta);
|
||||
}
|
||||
|
||||
/*
|
||||
* _clutter_meta_group_peek_metas:
|
||||
* @group: a #ClutterMetaGroup
|
||||
*
|
||||
* Returns a pointer to the #ClutterActorMeta list
|
||||
*
|
||||
* Return value: a const pointer to the #GList of #ClutterActorMeta
|
||||
*/
|
||||
const GList *
|
||||
_clutter_meta_group_peek_metas (ClutterMetaGroup *group)
|
||||
{
|
||||
return group->meta;
|
||||
}
|
||||
|
||||
/*
|
||||
* _clutter_meta_group_get_metas_no_internal:
|
||||
* @group: a #ClutterMetaGroup
|
||||
*
|
||||
* Returns a new allocated list containing all of the metas that don't
|
||||
* have an internal priority.
|
||||
*
|
||||
* Return value: A GList containing non-internal metas. Free with
|
||||
* g_list_free.
|
||||
*/
|
||||
GList *
|
||||
_clutter_meta_group_get_metas_no_internal (ClutterMetaGroup *group)
|
||||
{
|
||||
GList *ret = NULL;
|
||||
GList *l;
|
||||
|
||||
/* Build a new list filtering out the internal metas */
|
||||
for (l = group->meta; l; l = l->next)
|
||||
if (!_clutter_actor_meta_is_internal (l->data))
|
||||
ret = g_list_prepend (ret, l->data);
|
||||
|
||||
return g_list_reverse (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* _clutter_meta_group_has_metas_no_internal:
|
||||
* @group: a #ClutterMetaGroup
|
||||
*
|
||||
* Returns whether the group has any metas that don't have an internal priority.
|
||||
*
|
||||
* Return value: %TRUE if metas without internal priority exist
|
||||
* %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
_clutter_meta_group_has_metas_no_internal (ClutterMetaGroup *group)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = group->meta; l; l = l->next)
|
||||
if (!_clutter_actor_meta_is_internal (l->data))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* _clutter_meta_group_clear_metas:
|
||||
* @group: a #ClutterMetaGroup
|
||||
*
|
||||
* Clears @group of all #ClutterActorMeta instances and releases
|
||||
* the reference on them
|
||||
*/
|
||||
void
|
||||
_clutter_meta_group_clear_metas (ClutterMetaGroup *group)
|
||||
{
|
||||
g_list_foreach (group->meta, (GFunc) _clutter_actor_meta_set_actor, NULL);
|
||||
|
||||
g_list_free_full (group->meta, g_object_unref);
|
||||
group->meta = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* _clutter_meta_group_clear_metas_no_internal:
|
||||
* @group: a #ClutterMetaGroup
|
||||
*
|
||||
* Clears @group of all #ClutterActorMeta instances that don't have an
|
||||
* internal priority and releases the reference on them
|
||||
*/
|
||||
void
|
||||
_clutter_meta_group_clear_metas_no_internal (ClutterMetaGroup *group)
|
||||
{
|
||||
GList *internal_list = NULL;
|
||||
GList *l, *next;
|
||||
|
||||
for (l = group->meta; l; l = next)
|
||||
{
|
||||
next = l->next;
|
||||
|
||||
if (_clutter_actor_meta_is_internal (l->data))
|
||||
{
|
||||
if (internal_list)
|
||||
internal_list->prev = l;
|
||||
l->next = internal_list;
|
||||
l->prev = NULL;
|
||||
internal_list = l;
|
||||
}
|
||||
else
|
||||
{
|
||||
_clutter_actor_meta_set_actor (l->data, NULL);
|
||||
g_object_unref (l->data);
|
||||
g_list_free_1 (l);
|
||||
}
|
||||
}
|
||||
|
||||
group->meta = g_list_reverse (internal_list);
|
||||
}
|
||||
|
||||
/*
|
||||
* _clutter_meta_group_get_meta:
|
||||
* @group: a #ClutterMetaGroup
|
||||
* @name: the name of the #ClutterActorMeta to retrieve
|
||||
*
|
||||
* Retrieves a named #ClutterActorMeta from @group
|
||||
*
|
||||
* Return value: a #ClutterActorMeta for the given name, or %NULL
|
||||
*/
|
||||
ClutterActorMeta *
|
||||
_clutter_meta_group_get_meta (ClutterMetaGroup *group,
|
||||
const gchar *name)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = group->meta; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterActorMeta *meta = l->data;
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
if (g_strcmp0 (priv->name, name) == 0)
|
||||
return meta;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* clutter_actor_meta_get_debug_name:
|
||||
* @meta: a #ClutterActorMeta
|
||||
*
|
||||
* Retrieves the name of the @meta for debugging purposes.
|
||||
*
|
||||
* Return value: (transfer none): the name of the @meta. The returned
|
||||
* string is owned by the @meta instance and it should not be
|
||||
* modified or freed
|
||||
*/
|
||||
const gchar *
|
||||
_clutter_actor_meta_get_debug_name (ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
return priv->name != NULL ? priv->name : G_OBJECT_TYPE_NAME (meta);
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_ACTOR_META (clutter_actor_meta_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterActorMeta, clutter_actor_meta,
|
||||
CLUTTER, ACTOR_META, GInitiallyUnowned);
|
||||
|
||||
typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate;
|
||||
|
||||
/**
|
||||
* ClutterActorMetaClass:
|
||||
* @set_actor: virtual function, invoked when attaching and detaching
|
||||
* a #ClutterActorMeta instance to a #ClutterActor
|
||||
*
|
||||
* The #ClutterActorMetaClass structure contains
|
||||
* only private data
|
||||
*/
|
||||
struct _ClutterActorMetaClass
|
||||
{
|
||||
/*< private >*/
|
||||
GInitiallyUnownedClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
|
||||
/**
|
||||
* ClutterActorMetaClass::set_actor:
|
||||
* @meta: a #ClutterActorMeta
|
||||
* @actor: (allow-none): the actor attached to @meta, or %NULL
|
||||
*
|
||||
* Virtual function, called when @meta is attached or detached
|
||||
* from a #ClutterActor.
|
||||
*/
|
||||
void (* set_actor) (ClutterActorMeta *meta,
|
||||
ClutterActor *actor);
|
||||
|
||||
void (* set_enabled) (ClutterActorMeta *meta,
|
||||
gboolean is_enabled);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_meta_set_name (ClutterActorMeta *meta,
|
||||
const gchar *name);
|
||||
CLUTTER_EXPORT
|
||||
const gchar * clutter_actor_meta_get_name (ClutterActorMeta *meta);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
|
||||
gboolean is_enabled);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_meta_get_enabled (ClutterActorMeta *meta);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_actor_meta_get_actor (ClutterActorMeta *meta);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,305 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "clutter/clutter-actor.h"
|
||||
#include "clutter/clutter-grab.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*
|
||||
* Auxiliary define, in order to get the clutter actor from the AtkObject using
|
||||
* AtkGObject methods
|
||||
*
|
||||
*/
|
||||
#define CLUTTER_ACTOR_FROM_ACCESSIBLE(accessible) \
|
||||
(CLUTTER_ACTOR (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible))))
|
||||
|
||||
/**
|
||||
* ClutterActorFlags:
|
||||
* @CLUTTER_ACTOR_MAPPED: the actor will be painted (is visible, and inside
|
||||
* 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
|
||||
* signals
|
||||
* @CLUTTER_ACTOR_VISIBLE: the actor has been shown by the application program
|
||||
* @CLUTTER_ACTOR_NO_LAYOUT: the actor provides an explicit layout management
|
||||
* policy for its children; this flag will prevent Clutter from automatic
|
||||
* queueing of relayout and will defer all layouting to the actor itself
|
||||
*
|
||||
* Flags used to signal the state of an actor.
|
||||
*/
|
||||
typedef enum /*< prefix=CLUTTER_ACTOR >*/
|
||||
{
|
||||
CLUTTER_ACTOR_MAPPED = 1 << 1,
|
||||
CLUTTER_ACTOR_REALIZED = 1 << 2,
|
||||
CLUTTER_ACTOR_REACTIVE = 1 << 3,
|
||||
CLUTTER_ACTOR_VISIBLE = 1 << 4,
|
||||
CLUTTER_ACTOR_NO_LAYOUT = 1 << 5
|
||||
} ClutterActorFlags;
|
||||
|
||||
/*< private >
|
||||
* ClutterActorTraverseFlags:
|
||||
* CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST: Traverse the graph in
|
||||
* a depth first order.
|
||||
* CLUTTER_ACTOR_TRAVERSE_BREADTH_FIRST: Traverse the graph in a
|
||||
* breadth first order.
|
||||
*
|
||||
* Controls some options for how clutter_actor_traverse() iterates
|
||||
* through the graph.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST = 1L<<0,
|
||||
CLUTTER_ACTOR_TRAVERSE_BREADTH_FIRST = 1L<<1
|
||||
} ClutterActorTraverseFlags;
|
||||
|
||||
/*< private >
|
||||
* ClutterActorTraverseVisitFlags:
|
||||
* CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE: Continue traversing as
|
||||
* normal
|
||||
* CLUTTER_ACTOR_TRAVERSE_VISIT_SKIP_CHILDREN: Don't traverse the
|
||||
* children of the last visited actor. (Not applicable when using
|
||||
* %CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST_POST_ORDER since the children
|
||||
* are visited before having an opportunity to bail out)
|
||||
* CLUTTER_ACTOR_TRAVERSE_VISIT_BREAK: Immediately bail out without
|
||||
* visiting any more actors.
|
||||
*
|
||||
* Each time an actor is visited during a scenegraph traversal the
|
||||
* ClutterTraverseCallback can return a set of flags that may affect
|
||||
* the continuing traversal. It may stop traversal completely, just
|
||||
* skip over children for the current actor or continue as normal.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE = 1L<<0,
|
||||
CLUTTER_ACTOR_TRAVERSE_VISIT_SKIP_CHILDREN = 1L<<1,
|
||||
CLUTTER_ACTOR_TRAVERSE_VISIT_BREAK = 1L<<2
|
||||
} ClutterActorTraverseVisitFlags;
|
||||
|
||||
/*< private >
|
||||
* ClutterTraverseCallback:
|
||||
*
|
||||
* The callback prototype used with clutter_actor_traverse. The
|
||||
* returned flags can be used to affect the continuing traversal
|
||||
* either by continuing as normal, skipping over children of an
|
||||
* actor or bailing out completely.
|
||||
*/
|
||||
typedef ClutterActorTraverseVisitFlags (*ClutterTraverseCallback) (ClutterActor *actor,
|
||||
gint depth,
|
||||
gpointer user_data);
|
||||
|
||||
/*< private >
|
||||
* ClutterForeachCallback:
|
||||
* @actor: The actor being iterated
|
||||
* @user_data: The private data specified when starting the iteration
|
||||
*
|
||||
* A generic callback for iterating over actor, such as with
|
||||
* _clutter_actor_foreach_child.
|
||||
*
|
||||
* Return value: %TRUE to continue iterating or %FALSE to break iteration
|
||||
* early.
|
||||
*/
|
||||
typedef gboolean (*ClutterForeachCallback) (ClutterActor *actor,
|
||||
gpointer user_data);
|
||||
|
||||
typedef struct _SizeRequest SizeRequest;
|
||||
|
||||
typedef struct _ClutterLayoutInfo ClutterLayoutInfo;
|
||||
typedef struct _ClutterTransformInfo ClutterTransformInfo;
|
||||
typedef struct _ClutterAnimationInfo ClutterAnimationInfo;
|
||||
|
||||
struct _SizeRequest
|
||||
{
|
||||
guint age;
|
||||
gfloat for_size;
|
||||
gfloat min_size;
|
||||
gfloat natural_size;
|
||||
};
|
||||
|
||||
/*< private >
|
||||
* ClutterLayoutInfo:
|
||||
* @fixed_pos: the fixed position of the actor
|
||||
* @margin: the composed margin of the actor
|
||||
* @x_align: the horizontal alignment, if the actor expands horizontally
|
||||
* @y_align: the vertical alignment, if the actor expands vertically
|
||||
* @x_expand: whether the actor should expand horizontally
|
||||
* @y_expand: whether the actor should expand vertically
|
||||
* @minimum: the fixed minimum size
|
||||
* @natural: the fixed natural size
|
||||
*
|
||||
* Ancillary layout information for an actor.
|
||||
*/
|
||||
struct _ClutterLayoutInfo
|
||||
{
|
||||
/* fixed position coordinates */
|
||||
graphene_point_t fixed_pos;
|
||||
|
||||
ClutterMargin margin;
|
||||
|
||||
guint x_align : 4;
|
||||
guint y_align : 4;
|
||||
|
||||
guint x_expand : 1;
|
||||
guint y_expand : 1;
|
||||
|
||||
graphene_size_t minimum;
|
||||
graphene_size_t natural;
|
||||
};
|
||||
|
||||
const ClutterLayoutInfo * _clutter_actor_get_layout_info_or_defaults (ClutterActor *self);
|
||||
ClutterLayoutInfo * _clutter_actor_get_layout_info (ClutterActor *self);
|
||||
ClutterLayoutInfo * _clutter_actor_peek_layout_info (ClutterActor *self);
|
||||
|
||||
struct _ClutterTransformInfo
|
||||
{
|
||||
/* rotation */
|
||||
gdouble rx_angle;
|
||||
gdouble ry_angle;
|
||||
gdouble rz_angle;
|
||||
|
||||
/* scaling */
|
||||
gdouble scale_x;
|
||||
gdouble scale_y;
|
||||
gdouble scale_z;
|
||||
|
||||
/* translation */
|
||||
graphene_point3d_t translation;
|
||||
|
||||
/* z_position */
|
||||
gfloat z_position;
|
||||
|
||||
/* transformation center */
|
||||
graphene_point_t pivot;
|
||||
gfloat pivot_z;
|
||||
|
||||
graphene_matrix_t transform;
|
||||
guint transform_set : 1;
|
||||
|
||||
graphene_matrix_t child_transform;
|
||||
guint child_transform_set : 1;
|
||||
};
|
||||
|
||||
const ClutterTransformInfo * _clutter_actor_get_transform_info_or_defaults (ClutterActor *self);
|
||||
ClutterTransformInfo * _clutter_actor_get_transform_info (ClutterActor *self);
|
||||
|
||||
typedef struct _AState {
|
||||
guint easing_duration;
|
||||
guint easing_delay;
|
||||
ClutterAnimationMode easing_mode;
|
||||
} AState;
|
||||
|
||||
struct _ClutterAnimationInfo
|
||||
{
|
||||
GArray *states;
|
||||
AState *cur_state;
|
||||
|
||||
GHashTable *transitions;
|
||||
};
|
||||
|
||||
const ClutterAnimationInfo * _clutter_actor_get_animation_info_or_defaults (ClutterActor *self);
|
||||
ClutterAnimationInfo * _clutter_actor_get_animation_info (ClutterActor *self);
|
||||
|
||||
ClutterTransition * _clutter_actor_create_transition (ClutterActor *self,
|
||||
GParamSpec *pspec,
|
||||
...);
|
||||
gboolean _clutter_actor_foreach_child (ClutterActor *self,
|
||||
ClutterForeachCallback callback,
|
||||
gpointer user_data);
|
||||
void _clutter_actor_traverse (ClutterActor *actor,
|
||||
ClutterActorTraverseFlags flags,
|
||||
ClutterTraverseCallback before_children_callback,
|
||||
ClutterTraverseCallback after_children_callback,
|
||||
gpointer user_data);
|
||||
ClutterActor * _clutter_actor_get_stage_internal (ClutterActor *actor);
|
||||
|
||||
void _clutter_actor_apply_modelview_transform (ClutterActor *self,
|
||||
graphene_matrix_t *matrix);
|
||||
void _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self,
|
||||
ClutterActor *ancestor,
|
||||
graphene_matrix_t *matrix);
|
||||
|
||||
void _clutter_actor_set_in_clone_paint (ClutterActor *self,
|
||||
gboolean is_in_clone_paint);
|
||||
|
||||
void _clutter_actor_set_enable_model_view_transform (ClutterActor *self,
|
||||
gboolean enable);
|
||||
|
||||
void _clutter_actor_set_enable_paint_unmapped (ClutterActor *self,
|
||||
gboolean enable);
|
||||
|
||||
void _clutter_actor_set_has_pointer (ClutterActor *self,
|
||||
gboolean has_pointer);
|
||||
|
||||
void _clutter_actor_set_has_key_focus (ClutterActor *self,
|
||||
gboolean has_key_focus);
|
||||
|
||||
void _clutter_actor_queue_redraw_full (ClutterActor *self,
|
||||
const ClutterPaintVolume *volume,
|
||||
ClutterEffect *effect);
|
||||
|
||||
gboolean _clutter_actor_set_default_paint_volume (ClutterActor *self,
|
||||
GType check_gtype,
|
||||
ClutterPaintVolume *volume);
|
||||
|
||||
const char * _clutter_actor_get_debug_name (ClutterActor *self);
|
||||
|
||||
void _clutter_actor_push_clone_paint (void);
|
||||
void _clutter_actor_pop_clone_paint (void);
|
||||
|
||||
ClutterActorAlign _clutter_actor_get_effective_x_align (ClutterActor *self);
|
||||
|
||||
void _clutter_actor_attach_clone (ClutterActor *actor,
|
||||
ClutterActor *clone);
|
||||
void _clutter_actor_detach_clone (ClutterActor *actor,
|
||||
ClutterActor *clone);
|
||||
void _clutter_actor_queue_only_relayout (ClutterActor *actor);
|
||||
void clutter_actor_clear_stage_views_recursive (ClutterActor *actor,
|
||||
gboolean stop_transitions);
|
||||
|
||||
float clutter_actor_get_real_resource_scale (ClutterActor *actor);
|
||||
|
||||
void clutter_actor_finish_layout (ClutterActor *self,
|
||||
int phase);
|
||||
|
||||
void clutter_actor_queue_immediate_relayout (ClutterActor *self);
|
||||
|
||||
gboolean clutter_actor_is_painting_unmapped (ClutterActor *self);
|
||||
|
||||
void clutter_actor_attach_grab (ClutterActor *actor,
|
||||
ClutterGrab *grab);
|
||||
void clutter_actor_detach_grab (ClutterActor *actor,
|
||||
ClutterGrab *grab);
|
||||
|
||||
void clutter_actor_collect_event_actors (ClutterActor *self,
|
||||
ClutterActor *deepmost,
|
||||
GPtrArray *actors);
|
||||
|
||||
const GList * clutter_actor_peek_actions (ClutterActor *self);
|
||||
|
||||
void clutter_actor_set_implicitly_grabbed (ClutterActor *actor,
|
||||
gboolean is_implicitly_grabbed);
|
||||
|
||||
AtkStateSet * clutter_actor_get_accessible_state (ClutterActor *actor);
|
||||
|
||||
G_END_DECLS
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,898 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2006, 2007, 2008 OpenedHand Ltd
|
||||
* Copyright (C) 2009, 2010 Intel Corp
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
/* clutter-actor.h */
|
||||
|
||||
#include <atk/atk.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
#include "clutter/clutter-event.h"
|
||||
#include "clutter/clutter-paint-context.h"
|
||||
#include "clutter/clutter-pick-context.h"
|
||||
#include "mtk/mtk.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_ACTOR (clutter_actor_get_type ())
|
||||
#define CLUTTER_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTOR, ClutterActor))
|
||||
#define CLUTTER_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTOR, ClutterActorClass))
|
||||
#define CLUTTER_IS_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTOR))
|
||||
#define CLUTTER_IS_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTOR))
|
||||
#define CLUTTER_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTOR, ClutterActorClass))
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActor, g_object_unref)
|
||||
|
||||
typedef struct _ClutterActorClass ClutterActorClass;
|
||||
typedef struct _ClutterActorPrivate ClutterActorPrivate;
|
||||
|
||||
|
||||
struct _ClutterActor
|
||||
{
|
||||
/*< private >*/
|
||||
GInitiallyUnowned parent_instance;
|
||||
|
||||
/*< public >*/
|
||||
guint32 flags;
|
||||
AtkRole accessible_role;
|
||||
|
||||
/*< private >*/
|
||||
guint32 private_flags;
|
||||
|
||||
ClutterActorPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterActorClass:
|
||||
* @show: signal class handler for [signal@Clutter.Actor::show]; it must chain
|
||||
* up to the parent's implementation
|
||||
* @hide: signal class handler for [signal@Clutter.Actor::hide]; it must chain
|
||||
* up to the parent's implementation
|
||||
* @hide_all: virtual function for containers and composite actors, to
|
||||
* determine which children should be shown when calling
|
||||
* clutter_actor_hide_all() on the actor. Defaults to calling
|
||||
* clutter_actor_hide(). This virtual function is deprecated and it
|
||||
* should not be overridden.
|
||||
* @realize: virtual function, used to allocate resources for the actor;
|
||||
* it should chain up to the parent's implementation. This virtual
|
||||
* function is deprecated and should not be overridden in newly
|
||||
* written code.
|
||||
* @unrealize: virtual function, used to deallocate resources allocated
|
||||
* in ::realize; it should chain up to the parent's implementation. This
|
||||
* function is deprecated and should not be overridden in newly
|
||||
* written code.
|
||||
* @map: virtual function for containers and composite actors, to
|
||||
* map their children; it must chain up to the parent's implementation.
|
||||
* Overriding this function is optional.
|
||||
* @unmap: virtual function for containers and composite actors, to
|
||||
* unmap their children; it must chain up to the parent's implementation.
|
||||
* Overriding this function is optional.
|
||||
* @paint: virtual function, used to paint the actor
|
||||
* @get_preferred_width: virtual function, used when querying the minimum
|
||||
* and natural widths of an actor for a given height; it is used by
|
||||
* clutter_actor_get_preferred_width()
|
||||
* @get_preferred_height: virtual function, used when querying the minimum
|
||||
* and natural heights of an actor for a given width; it is used by
|
||||
* clutter_actor_get_preferred_height()
|
||||
* @allocate: virtual function, used when setting the coordinates of an
|
||||
* actor; it is used by clutter_actor_allocate(); when overriding this
|
||||
* function without chaining up, clutter_actor_set_allocation() must be
|
||||
* called and children must be allocated by the implementation, when
|
||||
* chaining up though, those things will be done by the parent's
|
||||
* implementation.
|
||||
* @apply_transform: virtual function, used when applying the transformations
|
||||
* to an actor before painting it or when transforming coordinates or
|
||||
* the allocation; if the transformation calculated by this function may
|
||||
* have changed, the cached transformation must be invalidated by calling
|
||||
* clutter_actor_invalidate_transform(); it must chain up to the parent's
|
||||
* implementation
|
||||
* @parent_set: signal class handler for the [signal@Clutter.Actor::parent-set]
|
||||
* @destroy: signal class handler for [signal@Clutter.Actor::destroy]. It must
|
||||
* chain up to the parent's implementation
|
||||
* @pick: virtual function, used to draw an outline of the actor with
|
||||
* the given color
|
||||
* @event: class handler for [signal@Clutter.Actor::event]
|
||||
* @button_press_event: class handler for [signal@Clutter.Actor::button-press-event]
|
||||
* @button_release_event: class handler for
|
||||
* [signal@Clutter.Actor::button-release-event]
|
||||
* @scroll_event: signal class closure for [signal@Clutter.Actor::scroll-event]
|
||||
* @key_press_event: signal class closure for [signal@Clutter.Actor::key-press-event]
|
||||
* @key_release_event: signal class closure for
|
||||
* [signal@Clutter.Actor::key-release-event]
|
||||
* @motion_event: signal class closure for [signal@Clutter.Actor::motion-event]
|
||||
* @enter_event: signal class closure for [signal@Clutter.Actor::enter-event]
|
||||
* @leave_event: signal class closure for [signal@Clutter.Actor::leave-event]
|
||||
* @captured_event: signal class closure for [signal@Clutter.Actor::captured-event]
|
||||
* @key_focus_in: signal class closure for [signal@Clutter.Actor::key-focus-in]
|
||||
* @key_focus_out: signal class closure for [signal@Clutter.Actor::key-focus-out]
|
||||
* @queue_relayout: class handler for [signal@Clutter.Actor::queue-relayout]
|
||||
* @get_accessible: virtual function, returns the accessible object that
|
||||
* describes the actor to an assistive technology.
|
||||
* @get_accessible_type: returns the type of the accessible object that
|
||||
* describes the actor to an assistive technology.
|
||||
* @get_paint_volume: virtual function, for sub-classes to define their
|
||||
* #ClutterPaintVolume
|
||||
* @has_overlaps: virtual function for
|
||||
* sub-classes to advertise whether they need an offscreen redirect
|
||||
* to get the correct opacity. See
|
||||
* clutter_actor_set_offscreen_redirect() for details.
|
||||
* @paint_node: virtual function for creating paint nodes and attaching
|
||||
* them to the render tree
|
||||
* @touch_event: signal class closure for [signal@Clutter.Actor::touch-event]
|
||||
*
|
||||
* Base class for actors.
|
||||
*/
|
||||
struct _ClutterActorClass
|
||||
{
|
||||
/*< private >*/
|
||||
GInitiallyUnownedClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
void (* show) (ClutterActor *self);
|
||||
void (* hide) (ClutterActor *self);
|
||||
void (* hide_all) (ClutterActor *self);
|
||||
void (* realize) (ClutterActor *self);
|
||||
void (* unrealize) (ClutterActor *self);
|
||||
void (* map) (ClutterActor *self);
|
||||
void (* unmap) (ClutterActor *self);
|
||||
void (* paint) (ClutterActor *self,
|
||||
ClutterPaintContext *paint_context);
|
||||
void (* parent_set) (ClutterActor *actor,
|
||||
ClutterActor *old_parent);
|
||||
|
||||
void (* destroy) (ClutterActor *self);
|
||||
void (* pick) (ClutterActor *actor,
|
||||
ClutterPickContext *pick_context);
|
||||
|
||||
/* size negotiation */
|
||||
void (* get_preferred_width) (ClutterActor *self,
|
||||
gfloat for_height,
|
||||
gfloat *min_width_p,
|
||||
gfloat *natural_width_p);
|
||||
void (* get_preferred_height) (ClutterActor *self,
|
||||
gfloat for_width,
|
||||
gfloat *min_height_p,
|
||||
gfloat *natural_height_p);
|
||||
void (* allocate) (ClutterActor *self,
|
||||
const ClutterActorBox *box);
|
||||
|
||||
/* transformations */
|
||||
void (* apply_transform) (ClutterActor *actor,
|
||||
graphene_matrix_t *matrix);
|
||||
|
||||
/* event signals */
|
||||
gboolean (* event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
gboolean (* button_press_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
gboolean (* button_release_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
gboolean (* scroll_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
gboolean (* key_press_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
gboolean (* key_release_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
gboolean (* motion_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
gboolean (* enter_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
gboolean (* leave_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
gboolean (* captured_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
void (* key_focus_in) (ClutterActor *actor);
|
||||
void (* key_focus_out) (ClutterActor *actor);
|
||||
|
||||
void (* queue_relayout) (ClutterActor *self);
|
||||
|
||||
/* accessibility support */
|
||||
AtkObject * (* get_accessible) (ClutterActor *self);
|
||||
GType (* get_accessible_type) (void);
|
||||
|
||||
gboolean (* get_paint_volume) (ClutterActor *actor,
|
||||
ClutterPaintVolume *volume);
|
||||
|
||||
gboolean (* has_overlaps) (ClutterActor *self);
|
||||
|
||||
void (* paint_node) (ClutterActor *self,
|
||||
ClutterPaintNode *root,
|
||||
ClutterPaintContext *paint_context);
|
||||
|
||||
gboolean (* touch_event) (ClutterActor *self,
|
||||
ClutterEvent *event);
|
||||
void (* resource_scale_changed) (ClutterActor *self);
|
||||
float (* calculate_resource_scale) (ClutterActor *self,
|
||||
int phase);
|
||||
|
||||
void (* child_added) (ClutterActor *self,
|
||||
ClutterActor *child);
|
||||
void (* child_removed) (ClutterActor *self,
|
||||
ClutterActor *child);
|
||||
|
||||
/* private */
|
||||
GType layout_manager_type;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterActorIter:
|
||||
*
|
||||
* An iterator structure that allows to efficiently iterate over a
|
||||
* section of the scene graph.
|
||||
*
|
||||
* The contents of the #ClutterActorIter structure
|
||||
* are private and should only be accessed using the provided API.
|
||||
*/
|
||||
struct _ClutterActorIter
|
||||
{
|
||||
/*< private >*/
|
||||
gpointer CLUTTER_PRIVATE_FIELD (dummy1);
|
||||
gpointer CLUTTER_PRIVATE_FIELD (dummy2);
|
||||
gint CLUTTER_PRIVATE_FIELD (dummy3);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_actor_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_actor_new (void);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_show (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_hide (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_realize (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_unrealize (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_map (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_unmap (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_paint (ClutterActor *self,
|
||||
ClutterPaintContext *paint_context);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_continue_paint (ClutterActor *self,
|
||||
ClutterPaintContext *paint_context);
|
||||
CLUTTER_EXPORT
|
||||
ClutterPaintNode * clutter_actor_create_texture_paint_node (ClutterActor *self,
|
||||
CoglTexture *texture);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_pick (ClutterActor *actor,
|
||||
ClutterPickContext *pick_context);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_continue_pick (ClutterActor *actor,
|
||||
ClutterPickContext *pick_context);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_queue_redraw (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_queue_redraw_with_clip (ClutterActor *self,
|
||||
const MtkRectangle *clip);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_queue_relayout (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_destroy (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_name (ClutterActor *self,
|
||||
const gchar *name);
|
||||
CLUTTER_EXPORT
|
||||
const gchar * clutter_actor_get_name (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_accessible_role (ClutterActor *self,
|
||||
AtkRole role);
|
||||
CLUTTER_EXPORT
|
||||
AtkRole clutter_actor_get_accessible_role (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_accessible_name (ClutterActor *self,
|
||||
const gchar *name);
|
||||
CLUTTER_EXPORT
|
||||
const gchar * clutter_actor_get_accessible_name (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
AtkObject * clutter_actor_get_accessible (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_accessible (ClutterActor *self,
|
||||
AtkObject *accessible);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_add_accessible_state (ClutterActor *actor,
|
||||
AtkStateType state);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_remove_accessible_state (ClutterActor *actor,
|
||||
AtkStateType state);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_is_visible (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_is_mapped (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_is_realized (ClutterActor *self);
|
||||
|
||||
/* Size negotiation */
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_no_layout (ClutterActor *actor,
|
||||
gboolean no_layout);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_is_no_layout (ClutterActor *actor);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_request_mode (ClutterActor *self,
|
||||
ClutterRequestMode mode);
|
||||
CLUTTER_EXPORT
|
||||
ClutterRequestMode clutter_actor_get_request_mode (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_preferred_width (ClutterActor *self,
|
||||
gfloat for_height,
|
||||
gfloat *min_width_p,
|
||||
gfloat *natural_width_p);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_preferred_height (ClutterActor *self,
|
||||
gfloat for_width,
|
||||
gfloat *min_height_p,
|
||||
gfloat *natural_height_p);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_preferred_size (ClutterActor *self,
|
||||
gfloat *min_width_p,
|
||||
gfloat *min_height_p,
|
||||
gfloat *natural_width_p,
|
||||
gfloat *natural_height_p);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_allocate_preferred_size (ClutterActor *self,
|
||||
float x,
|
||||
float y);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_allocate_available_size (ClutterActor *self,
|
||||
gfloat x,
|
||||
gfloat y,
|
||||
gfloat available_width,
|
||||
gfloat available_height);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_allocate_align_fill (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
gdouble x_align,
|
||||
gdouble y_align,
|
||||
gboolean x_fill,
|
||||
gboolean y_fill);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_allocation (ClutterActor *self,
|
||||
const ClutterActorBox *box);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_allocation_box (ClutterActor *self,
|
||||
ClutterActorBox *box);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_has_allocation (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_size (ClutterActor *self,
|
||||
gfloat width,
|
||||
gfloat height);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_size (ClutterActor *self,
|
||||
gfloat *width,
|
||||
gfloat *height);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_position (ClutterActor *self,
|
||||
gfloat x,
|
||||
gfloat y);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_get_fixed_position (ClutterActor *self,
|
||||
float *x,
|
||||
float *y);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_position (ClutterActor *self,
|
||||
gfloat *x,
|
||||
gfloat *y);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_get_fixed_position_set (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_fixed_position_set (ClutterActor *self,
|
||||
gboolean is_set);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_move_by (ClutterActor *self,
|
||||
gfloat dx,
|
||||
gfloat dy);
|
||||
|
||||
/* Actor geometry */
|
||||
CLUTTER_EXPORT
|
||||
gfloat clutter_actor_get_width (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gfloat clutter_actor_get_height (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_width (ClutterActor *self,
|
||||
gfloat width);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_height (ClutterActor *self,
|
||||
gfloat height);
|
||||
CLUTTER_EXPORT
|
||||
gfloat clutter_actor_get_x (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gfloat clutter_actor_get_y (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_x (ClutterActor *self,
|
||||
gfloat x);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_y (ClutterActor *self,
|
||||
gfloat y);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_z_position (ClutterActor *self,
|
||||
gfloat z_position);
|
||||
CLUTTER_EXPORT
|
||||
gfloat clutter_actor_get_z_position (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_layout_manager (ClutterActor *self,
|
||||
ClutterLayoutManager *manager);
|
||||
CLUTTER_EXPORT
|
||||
ClutterLayoutManager * clutter_actor_get_layout_manager (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_x_align (ClutterActor *self,
|
||||
ClutterActorAlign x_align);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActorAlign clutter_actor_get_x_align (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_y_align (ClutterActor *self,
|
||||
ClutterActorAlign y_align);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActorAlign clutter_actor_get_y_align (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_margin_top (ClutterActor *self,
|
||||
gfloat margin);
|
||||
CLUTTER_EXPORT
|
||||
gfloat clutter_actor_get_margin_top (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_margin_bottom (ClutterActor *self,
|
||||
gfloat margin);
|
||||
CLUTTER_EXPORT
|
||||
gfloat clutter_actor_get_margin_bottom (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_margin_left (ClutterActor *self,
|
||||
gfloat margin);
|
||||
CLUTTER_EXPORT
|
||||
gfloat clutter_actor_get_margin_left (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_margin_right (ClutterActor *self,
|
||||
gfloat margin);
|
||||
CLUTTER_EXPORT
|
||||
gfloat clutter_actor_get_margin_right (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_margin (ClutterActor *self,
|
||||
const ClutterMargin *margin);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_margin (ClutterActor *self,
|
||||
ClutterMargin *margin);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_x_expand (ClutterActor *self,
|
||||
gboolean expand);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_get_x_expand (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_y_expand (ClutterActor *self,
|
||||
gboolean expand);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_get_y_expand (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_needs_expand (ClutterActor *self,
|
||||
ClutterOrientation orientation);
|
||||
|
||||
/* Paint */
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_clip (ClutterActor *self,
|
||||
gfloat xoff,
|
||||
gfloat yoff,
|
||||
gfloat width,
|
||||
gfloat height);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_remove_clip (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_has_clip (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_clip (ClutterActor *self,
|
||||
gfloat *xoff,
|
||||
gfloat *yoff,
|
||||
gfloat *width,
|
||||
gfloat *height);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_clip_to_allocation (ClutterActor *self,
|
||||
gboolean clip_set);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_get_clip_to_allocation (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_opacity (ClutterActor *self,
|
||||
guint8 opacity);
|
||||
CLUTTER_EXPORT
|
||||
guint8 clutter_actor_get_opacity (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
guint8 clutter_actor_get_paint_opacity (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_get_paint_visibility (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_offscreen_redirect (ClutterActor *self,
|
||||
ClutterOffscreenRedirect redirect);
|
||||
CLUTTER_EXPORT
|
||||
ClutterOffscreenRedirect clutter_actor_get_offscreen_redirect (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_should_pick (ClutterActor *self,
|
||||
ClutterPickContext *pick_context);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_is_in_clone_paint (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_get_paint_box (ClutterActor *self,
|
||||
ClutterActorBox *box);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
float clutter_actor_get_resource_scale (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_has_overlaps (ClutterActor *self);
|
||||
|
||||
/* Content */
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_content (ClutterActor *self,
|
||||
ClutterContent *content);
|
||||
CLUTTER_EXPORT
|
||||
ClutterContent * clutter_actor_get_content (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_content_gravity (ClutterActor *self,
|
||||
ClutterContentGravity gravity);
|
||||
CLUTTER_EXPORT
|
||||
ClutterContentGravity clutter_actor_get_content_gravity (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_content_scaling_filters (ClutterActor *self,
|
||||
ClutterScalingFilter min_filter,
|
||||
ClutterScalingFilter mag_filter);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_content_scaling_filters (ClutterActor *self,
|
||||
ClutterScalingFilter *min_filter,
|
||||
ClutterScalingFilter *mag_filter);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_content_repeat (ClutterActor *self,
|
||||
ClutterContentRepeat repeat);
|
||||
CLUTTER_EXPORT
|
||||
ClutterContentRepeat clutter_actor_get_content_repeat (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_color_state (ClutterActor *self,
|
||||
ClutterColorState *color_state);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_unset_color_state (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterColorState * clutter_actor_get_color_state (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_content_box (ClutterActor *self,
|
||||
ClutterActorBox *box);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_background_color (ClutterActor *self,
|
||||
const CoglColor *color);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_background_color (ClutterActor *self,
|
||||
CoglColor *color);
|
||||
CLUTTER_EXPORT
|
||||
const ClutterPaintVolume * clutter_actor_get_paint_volume (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
ClutterPaintVolume * clutter_actor_get_transformed_paint_volume (ClutterActor *self,
|
||||
ClutterActor *relative_to_ancestor);
|
||||
|
||||
/* Events */
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_reactive (ClutterActor *actor,
|
||||
gboolean reactive);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_get_reactive (ClutterActor *actor);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_has_key_focus (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_grab_key_focus (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_event (ClutterActor *actor,
|
||||
const ClutterEvent *event,
|
||||
gboolean capture);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_has_pointer (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_text_direction (ClutterActor *self,
|
||||
ClutterTextDirection text_dir);
|
||||
CLUTTER_EXPORT
|
||||
ClutterTextDirection clutter_actor_get_text_direction (ClutterActor *self);
|
||||
|
||||
/* Actor hierarchy */
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_add_child (ClutterActor *self,
|
||||
ClutterActor *child);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_insert_child_at_index (ClutterActor *self,
|
||||
ClutterActor *child,
|
||||
gint index_);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_insert_child_above (ClutterActor *self,
|
||||
ClutterActor *child,
|
||||
ClutterActor *sibling);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_insert_child_below (ClutterActor *self,
|
||||
ClutterActor *child,
|
||||
ClutterActor *sibling);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_replace_child (ClutterActor *self,
|
||||
ClutterActor *old_child,
|
||||
ClutterActor *new_child);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_remove_child (ClutterActor *self,
|
||||
ClutterActor *child);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_remove_all_children (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_destroy_all_children (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
GList * clutter_actor_get_children (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gint clutter_actor_get_n_children (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_actor_get_child_at_index (ClutterActor *self,
|
||||
gint index_);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_actor_get_previous_sibling (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_actor_get_next_sibling (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_actor_get_first_child (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_actor_get_last_child (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_actor_get_parent (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_contains (ClutterActor *self,
|
||||
ClutterActor *descendant);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor* clutter_actor_get_stage (ClutterActor *actor);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterContext * clutter_actor_get_context (ClutterActor *actor);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_child_below_sibling (ClutterActor *self,
|
||||
ClutterActor *child,
|
||||
ClutterActor *sibling);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_child_above_sibling (ClutterActor *self,
|
||||
ClutterActor *child,
|
||||
ClutterActor *sibling);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_child_at_index (ClutterActor *self,
|
||||
ClutterActor *child,
|
||||
gint index_);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_iter_init (ClutterActorIter *iter,
|
||||
ClutterActor *root);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_iter_next (ClutterActorIter *iter,
|
||||
ClutterActor **child);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_iter_prev (ClutterActorIter *iter,
|
||||
ClutterActor **child);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_iter_remove (ClutterActorIter *iter);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_iter_destroy (ClutterActorIter *iter);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_iter_is_valid (const ClutterActorIter *iter);
|
||||
|
||||
/* Transformations */
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_is_rotated (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_is_scaled (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_pivot_point (ClutterActor *self,
|
||||
gfloat pivot_x,
|
||||
gfloat pivot_y);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_pivot_point (ClutterActor *self,
|
||||
gfloat *pivot_x,
|
||||
gfloat *pivot_y);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_pivot_point_z (ClutterActor *self,
|
||||
gfloat pivot_z);
|
||||
CLUTTER_EXPORT
|
||||
gfloat clutter_actor_get_pivot_point_z (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_rotation_angle (ClutterActor *self,
|
||||
ClutterRotateAxis axis,
|
||||
gdouble angle);
|
||||
CLUTTER_EXPORT
|
||||
gdouble clutter_actor_get_rotation_angle (ClutterActor *self,
|
||||
ClutterRotateAxis axis);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_scale (ClutterActor *self,
|
||||
gdouble scale_x,
|
||||
gdouble scale_y);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_scale (ClutterActor *self,
|
||||
gdouble *scale_x,
|
||||
gdouble *scale_y);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_scale_z (ClutterActor *self,
|
||||
gdouble scale_z);
|
||||
CLUTTER_EXPORT
|
||||
gdouble clutter_actor_get_scale_z (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_translation (ClutterActor *self,
|
||||
gfloat translate_x,
|
||||
gfloat translate_y,
|
||||
gfloat translate_z);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_translation (ClutterActor *self,
|
||||
gfloat *translate_x,
|
||||
gfloat *translate_y,
|
||||
gfloat *translate_z);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_transform (ClutterActor *self,
|
||||
const graphene_matrix_t *transform);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_transform (ClutterActor *self,
|
||||
graphene_matrix_t *transform);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_child_transform (ClutterActor *self,
|
||||
const graphene_matrix_t *transform);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_child_transform (ClutterActor *self,
|
||||
graphene_matrix_t *transform);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_transformed_extents (ClutterActor *self,
|
||||
graphene_rect_t *rect);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_transformed_position (ClutterActor *self,
|
||||
gfloat *x,
|
||||
gfloat *y);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_transformed_size (ClutterActor *self,
|
||||
gfloat *width,
|
||||
gfloat *height);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_transform_stage_point (ClutterActor *self,
|
||||
gfloat x,
|
||||
gfloat y,
|
||||
gfloat *x_out,
|
||||
gfloat *y_out);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_abs_allocation_vertices (ClutterActor *self,
|
||||
graphene_point3d_t *verts);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_apply_transform_to_point (ClutterActor *self,
|
||||
const graphene_point3d_t *point,
|
||||
graphene_point3d_t *vertex);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_apply_relative_transform_to_point (ClutterActor *self,
|
||||
ClutterActor *ancestor,
|
||||
const graphene_point3d_t *point,
|
||||
graphene_point3d_t *vertex);
|
||||
|
||||
/* Implicit animations */
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_save_easing_state (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_restore_easing_state (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_easing_mode (ClutterActor *self,
|
||||
ClutterAnimationMode mode);
|
||||
CLUTTER_EXPORT
|
||||
ClutterAnimationMode clutter_actor_get_easing_mode (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_easing_duration (ClutterActor *self,
|
||||
guint msecs);
|
||||
CLUTTER_EXPORT
|
||||
guint clutter_actor_get_easing_duration (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_easing_delay (ClutterActor *self,
|
||||
guint msecs);
|
||||
CLUTTER_EXPORT
|
||||
guint clutter_actor_get_easing_delay (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
ClutterTransition * clutter_actor_get_transition (ClutterActor *self,
|
||||
const char *name);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_add_transition (ClutterActor *self,
|
||||
const char *name,
|
||||
ClutterTransition *transition);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_remove_transition (ClutterActor *self,
|
||||
const char *name);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_remove_all_transitions (ClutterActor *self);
|
||||
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_has_mapped_clones (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_opacity_override (ClutterActor *self,
|
||||
gint opacity);
|
||||
CLUTTER_EXPORT
|
||||
gint clutter_actor_get_opacity_override (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_inhibit_culling (ClutterActor *actor);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_uninhibit_culling (ClutterActor *actor);
|
||||
|
||||
/**
|
||||
* ClutterActorCreateChildFunc:
|
||||
* @item: (type GObject): the item in the model
|
||||
* @user_data: Data passed to clutter_actor_bind_model()
|
||||
*
|
||||
* Creates a #ClutterActor using the @item in the model.
|
||||
*
|
||||
* The usual way to implement this function is to create a #ClutterActor
|
||||
* instance and then bind the #GObject properties to the actor properties
|
||||
* of interest, using g_object_bind_property(). This way, when the @item
|
||||
* in the #GListModel changes, the #ClutterActor changes as well.
|
||||
*
|
||||
* Returns: (transfer full): The newly created child #ClutterActor4
|
||||
*/
|
||||
typedef ClutterActor * (* ClutterActorCreateChildFunc) (gpointer item,
|
||||
gpointer user_data);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_bind_model (ClutterActor *self,
|
||||
GListModel *model,
|
||||
ClutterActorCreateChildFunc create_child_func,
|
||||
gpointer user_data,
|
||||
GDestroyNotify notify);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_bind_model_with_properties (ClutterActor *self,
|
||||
GListModel *model,
|
||||
GType child_type,
|
||||
const char *first_model_property,
|
||||
...);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_pick_box (ClutterActor *self,
|
||||
ClutterPickContext *pick_context,
|
||||
const ClutterActorBox *box);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GList * clutter_actor_peek_stage_views (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_invalidate_transform (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_invalidate_paint_volume (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_class_set_layout_manager_type (ClutterActorClass *actor_class,
|
||||
GType type);
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_actor_class_get_layout_manager_type (ClutterActorClass *actor_class);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,607 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterAlignConstraint:
|
||||
*
|
||||
* A constraint aligning the position of an actor
|
||||
*
|
||||
* #ClutterAlignConstraint is a [class@Constraint] that aligns the position
|
||||
* of the [class@Actor] to which it is applied to the size of another
|
||||
* [class@Actor] using an alignment factor
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-align-constraint.h"
|
||||
|
||||
#include "clutter/clutter-actor-meta-private.h"
|
||||
#include "clutter/clutter-actor-private.h"
|
||||
#include "clutter/clutter-constraint.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-enum-types.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
struct _ClutterAlignConstraint
|
||||
{
|
||||
ClutterConstraint parent_instance;
|
||||
|
||||
ClutterActor *actor;
|
||||
ClutterActor *source;
|
||||
ClutterAlignAxis align_axis;
|
||||
graphene_point_t pivot;
|
||||
gfloat factor;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_SOURCE,
|
||||
PROP_ALIGN_AXIS,
|
||||
PROP_PIVOT_POINT,
|
||||
PROP_FACTOR,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
G_DEFINE_FINAL_TYPE (ClutterAlignConstraint,
|
||||
clutter_align_constraint,
|
||||
CLUTTER_TYPE_CONSTRAINT);
|
||||
|
||||
static void
|
||||
source_queue_relayout (ClutterActor *actor,
|
||||
ClutterAlignConstraint *align)
|
||||
{
|
||||
if (align->actor != NULL)
|
||||
_clutter_actor_queue_only_relayout (align->actor);
|
||||
}
|
||||
|
||||
static void
|
||||
source_destroyed (ClutterActor *actor,
|
||||
ClutterAlignConstraint *align)
|
||||
{
|
||||
align->source = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_align_constraint_set_actor (ClutterActorMeta *meta,
|
||||
ClutterActor *new_actor)
|
||||
{
|
||||
ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (meta);
|
||||
ClutterActorMetaClass *parent;
|
||||
|
||||
if (new_actor != NULL &&
|
||||
align->source != NULL &&
|
||||
clutter_actor_contains (new_actor, align->source))
|
||||
{
|
||||
g_warning (G_STRLOC ": The source actor '%s' is contained "
|
||||
"by the actor '%s' associated to the constraint "
|
||||
"'%s'",
|
||||
_clutter_actor_get_debug_name (align->source),
|
||||
_clutter_actor_get_debug_name (new_actor),
|
||||
_clutter_actor_meta_get_debug_name (meta));
|
||||
return;
|
||||
}
|
||||
|
||||
/* store the pointer to the actor, for later use */
|
||||
align->actor = new_actor;
|
||||
|
||||
parent = CLUTTER_ACTOR_META_CLASS (clutter_align_constraint_parent_class);
|
||||
parent->set_actor (meta, new_actor);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_align_constraint_update_allocation (ClutterConstraint *constraint,
|
||||
ClutterActor *actor,
|
||||
ClutterActorBox *allocation)
|
||||
{
|
||||
ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (constraint);
|
||||
gfloat source_width, source_height;
|
||||
gfloat actor_width, actor_height;
|
||||
gfloat offset_x_start, offset_y_start;
|
||||
gfloat pivot_x, pivot_y;
|
||||
|
||||
if (align->source == NULL)
|
||||
return;
|
||||
|
||||
clutter_actor_box_get_size (allocation, &actor_width, &actor_height);
|
||||
|
||||
clutter_actor_get_size (align->source, &source_width, &source_height);
|
||||
|
||||
pivot_x = align->pivot.x == -1.f
|
||||
? align->factor
|
||||
: align->pivot.x;
|
||||
pivot_y = align->pivot.y == -1.f
|
||||
? align->factor
|
||||
: align->pivot.y;
|
||||
|
||||
offset_x_start = pivot_x * -actor_width;
|
||||
offset_y_start = pivot_y * -actor_height;
|
||||
|
||||
switch (align->align_axis)
|
||||
{
|
||||
case CLUTTER_ALIGN_X_AXIS:
|
||||
allocation->x1 += offset_x_start + (source_width * align->factor);
|
||||
allocation->x2 = allocation->x1 + actor_width;
|
||||
break;
|
||||
|
||||
case CLUTTER_ALIGN_Y_AXIS:
|
||||
allocation->y1 += offset_y_start + (source_height * align->factor);
|
||||
allocation->y2 = allocation->y1 + actor_height;
|
||||
break;
|
||||
|
||||
case CLUTTER_ALIGN_BOTH:
|
||||
allocation->x1 += offset_x_start + (source_width * align->factor);
|
||||
allocation->y1 += offset_y_start + (source_height * align->factor);
|
||||
allocation->x2 = allocation->x1 + actor_width;
|
||||
allocation->y2 = allocation->y1 + actor_height;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
clutter_actor_box_clamp_to_pixel (allocation);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_align_constraint_dispose (GObject *gobject)
|
||||
{
|
||||
ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (gobject);
|
||||
|
||||
if (align->source != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (align->source,
|
||||
G_CALLBACK (source_destroyed),
|
||||
align);
|
||||
g_signal_handlers_disconnect_by_func (align->source,
|
||||
G_CALLBACK (source_queue_relayout),
|
||||
align);
|
||||
align->source = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (clutter_align_constraint_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_align_constraint_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SOURCE:
|
||||
clutter_align_constraint_set_source (align, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_ALIGN_AXIS:
|
||||
clutter_align_constraint_set_align_axis (align, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
case PROP_PIVOT_POINT:
|
||||
clutter_align_constraint_set_pivot_point (align, g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
case PROP_FACTOR:
|
||||
clutter_align_constraint_set_factor (align, g_value_get_float (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_align_constraint_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SOURCE:
|
||||
g_value_set_object (value, align->source);
|
||||
break;
|
||||
|
||||
case PROP_ALIGN_AXIS:
|
||||
g_value_set_enum (value, align->align_axis);
|
||||
break;
|
||||
|
||||
case PROP_PIVOT_POINT:
|
||||
{
|
||||
graphene_point_t point;
|
||||
|
||||
clutter_align_constraint_get_pivot_point (align, &point);
|
||||
|
||||
g_value_set_boxed (value, &point);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_FACTOR:
|
||||
g_value_set_float (value, align->factor);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
|
||||
ClutterConstraintClass *constraint_class = CLUTTER_CONSTRAINT_CLASS (klass);
|
||||
|
||||
meta_class->set_actor = clutter_align_constraint_set_actor;
|
||||
|
||||
constraint_class->update_allocation = clutter_align_constraint_update_allocation;
|
||||
|
||||
/**
|
||||
* ClutterAlignConstraint:source:
|
||||
*
|
||||
* The #ClutterActor used as the source for the alignment.
|
||||
*
|
||||
* The #ClutterActor must not be a child or a grandchild of the actor
|
||||
* using the constraint.
|
||||
*/
|
||||
obj_props[PROP_SOURCE] =
|
||||
g_param_spec_object ("source", NULL, NULL,
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT);
|
||||
|
||||
/**
|
||||
* ClutterAlignConstraint:align-axis:
|
||||
*
|
||||
* The axis to be used to compute the alignment
|
||||
*/
|
||||
obj_props[PROP_ALIGN_AXIS] =
|
||||
g_param_spec_enum ("align-axis", NULL, NULL,
|
||||
CLUTTER_TYPE_ALIGN_AXIS,
|
||||
CLUTTER_ALIGN_X_AXIS,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT);
|
||||
|
||||
/**
|
||||
* ClutterAlignConstraint:pivot-point:
|
||||
*
|
||||
* The pivot point used by the constraint. The pivot point is the
|
||||
* point in the constraint actor around which the aligning is applied,
|
||||
* with (0, 0) being the top left corner of the actor and (1, 1) the
|
||||
* bottom right corner of the actor.
|
||||
*
|
||||
* For example, setting the pivot point to (0.5, 0.5) and using a factor
|
||||
* of 1 for both axes will align the actors horizontal and vertical
|
||||
* center point with the bottom right corner of the source actor.
|
||||
*
|
||||
* By default, the pivot point is set to (-1, -1), which means it's not
|
||||
* used and the constrained actor will be aligned to always stay inside
|
||||
* the source actor.
|
||||
*/
|
||||
obj_props[PROP_PIVOT_POINT] =
|
||||
g_param_spec_boxed ("pivot-point", NULL, NULL,
|
||||
GRAPHENE_TYPE_POINT,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterAlignConstraint:factor:
|
||||
*
|
||||
* The alignment factor, as a normalized value between 0.0 and 1.0
|
||||
*
|
||||
* The factor depends on the #ClutterAlignConstraint:align-axis property:
|
||||
* with an align-axis value of %CLUTTER_ALIGN_X_AXIS, 0.0 means left and
|
||||
* 1.0 means right; with a value of %CLUTTER_ALIGN_Y_AXIS, 0.0 means top
|
||||
* and 1.0 means bottom.
|
||||
*/
|
||||
obj_props[PROP_FACTOR] =
|
||||
g_param_spec_float ("factor", NULL, NULL,
|
||||
0.0, 1.0,
|
||||
0.0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT);
|
||||
|
||||
gobject_class->dispose = clutter_align_constraint_dispose;
|
||||
gobject_class->set_property = clutter_align_constraint_set_property;
|
||||
gobject_class->get_property = clutter_align_constraint_get_property;
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_align_constraint_init (ClutterAlignConstraint *self)
|
||||
{
|
||||
self->actor = NULL;
|
||||
self->source = NULL;
|
||||
self->align_axis = CLUTTER_ALIGN_X_AXIS;
|
||||
self->pivot.x = -1.f;
|
||||
self->pivot.y = -1.f;
|
||||
self->factor = 0.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_new:
|
||||
* @source: (allow-none): the #ClutterActor to use as the source of the
|
||||
* alignment, or %NULL
|
||||
* @axis: the axis to be used to compute the alignment
|
||||
* @factor: the alignment factor, between 0.0 and 1.0
|
||||
*
|
||||
* Creates a new constraint, aligning a #ClutterActor's position with
|
||||
* regards of the size of the actor to @source, with the given
|
||||
* alignment @factor
|
||||
*
|
||||
* Return value: the newly created #ClutterAlignConstraint
|
||||
*/
|
||||
ClutterConstraint *
|
||||
clutter_align_constraint_new (ClutterActor *source,
|
||||
ClutterAlignAxis axis,
|
||||
gfloat factor)
|
||||
{
|
||||
g_return_val_if_fail (source == NULL || CLUTTER_IS_ACTOR (source), NULL);
|
||||
|
||||
return g_object_new (CLUTTER_TYPE_ALIGN_CONSTRAINT,
|
||||
"source", source,
|
||||
"align-axis", axis,
|
||||
"factor", factor,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_set_source:
|
||||
* @align: a #ClutterAlignConstraint
|
||||
* @source: (allow-none): a #ClutterActor, or %NULL to unset the source
|
||||
*
|
||||
* Sets the source of the alignment constraint
|
||||
*/
|
||||
void
|
||||
clutter_align_constraint_set_source (ClutterAlignConstraint *align,
|
||||
ClutterActor *source)
|
||||
{
|
||||
ClutterActor *old_source, *actor;
|
||||
ClutterActorMeta *meta;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
|
||||
g_return_if_fail (source == NULL || CLUTTER_IS_ACTOR (source));
|
||||
|
||||
if (align->source == source)
|
||||
return;
|
||||
|
||||
meta = CLUTTER_ACTOR_META (align);
|
||||
actor = clutter_actor_meta_get_actor (meta);
|
||||
if (actor != NULL && source != NULL)
|
||||
{
|
||||
if (clutter_actor_contains (actor, source))
|
||||
{
|
||||
g_warning (G_STRLOC ": The source actor '%s' is contained "
|
||||
"by the actor '%s' associated to the constraint "
|
||||
"'%s'",
|
||||
_clutter_actor_get_debug_name (source),
|
||||
_clutter_actor_get_debug_name (actor),
|
||||
_clutter_actor_meta_get_debug_name (meta));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
old_source = align->source;
|
||||
if (old_source != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (old_source,
|
||||
G_CALLBACK (source_destroyed),
|
||||
align);
|
||||
g_signal_handlers_disconnect_by_func (old_source,
|
||||
G_CALLBACK (source_queue_relayout),
|
||||
align);
|
||||
}
|
||||
|
||||
align->source = source;
|
||||
if (align->source != NULL)
|
||||
{
|
||||
g_signal_connect (align->source, "queue-relayout",
|
||||
G_CALLBACK (source_queue_relayout),
|
||||
align);
|
||||
g_signal_connect (align->source, "destroy",
|
||||
G_CALLBACK (source_destroyed),
|
||||
align);
|
||||
|
||||
if (align->actor != NULL)
|
||||
clutter_actor_queue_relayout (align->actor);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_SOURCE]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_get_source:
|
||||
* @align: a #ClutterAlignConstraint
|
||||
*
|
||||
* Retrieves the source of the alignment
|
||||
*
|
||||
* Return value: (transfer none): the #ClutterActor used as the source
|
||||
* of the alignment
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_align_constraint_get_source (ClutterAlignConstraint *align)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align), NULL);
|
||||
|
||||
return align->source;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_set_align_axis:
|
||||
* @align: a #ClutterAlignConstraint
|
||||
* @axis: the axis to which the alignment refers to
|
||||
*
|
||||
* Sets the axis to which the alignment refers to
|
||||
*/
|
||||
void
|
||||
clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align,
|
||||
ClutterAlignAxis axis)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
|
||||
|
||||
if (align->align_axis == axis)
|
||||
return;
|
||||
|
||||
align->align_axis = axis;
|
||||
|
||||
if (align->actor != NULL)
|
||||
clutter_actor_queue_relayout (align->actor);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_ALIGN_AXIS]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_get_align_axis:
|
||||
* @align: a #ClutterAlignConstraint
|
||||
*
|
||||
* Retrieves the value set using [method@Clutter.AlignConstraint.set_align_axis]
|
||||
*
|
||||
* Return value: the alignment axis
|
||||
*/
|
||||
ClutterAlignAxis
|
||||
clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align),
|
||||
CLUTTER_ALIGN_X_AXIS);
|
||||
|
||||
return align->align_axis;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_set_pivot_point:
|
||||
* @align: a #ClutterAlignConstraint
|
||||
* @pivot_point: A #GraphenePoint
|
||||
*
|
||||
* Sets the pivot point used by the constraint, the pivot point is the
|
||||
* point in the constraint actor around which the aligning is applied,
|
||||
* with (0, 0) being the top left corner of the actor and (1, 1) the
|
||||
* bottom right corner of the actor.
|
||||
*
|
||||
* If -1 is used, the pivot point is unset and the constrained actor
|
||||
* will be aligned to always stay inside the source actor.
|
||||
*/
|
||||
void
|
||||
clutter_align_constraint_set_pivot_point (ClutterAlignConstraint *align,
|
||||
const graphene_point_t *pivot_point)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
|
||||
g_return_if_fail (pivot_point != NULL);
|
||||
g_return_if_fail (pivot_point->x == -1.f ||
|
||||
(pivot_point->x >= 0.f && pivot_point->x <= 1.f));
|
||||
g_return_if_fail (pivot_point->y == -1.f ||
|
||||
(pivot_point->y >= 0.f && pivot_point->y <= 1.f));
|
||||
|
||||
if (graphene_point_equal (&align->pivot, pivot_point))
|
||||
return;
|
||||
|
||||
align->pivot = *pivot_point;
|
||||
|
||||
if (align->actor != NULL)
|
||||
clutter_actor_queue_relayout (align->actor);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_PIVOT_POINT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_get_pivot_point
|
||||
* @align: a #ClutterAlignConstraint
|
||||
* @pivot_point: (out caller-allocates): return location for a #GraphenePoint
|
||||
*
|
||||
* Gets the pivot point used by the constraint set with
|
||||
* [method@Clutter.AlignConstraint.set_pivot_point]. If no custom pivot
|
||||
* point is set, -1 is set.
|
||||
*/
|
||||
void
|
||||
clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align,
|
||||
graphene_point_t *pivot_point)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
|
||||
g_return_if_fail (pivot_point != NULL);
|
||||
|
||||
*pivot_point = align->pivot;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_set_factor:
|
||||
* @align: a #ClutterAlignConstraint
|
||||
* @factor: the alignment factor, between 0.0 and 1.0
|
||||
*
|
||||
* Sets the alignment factor of the constraint
|
||||
*
|
||||
* The factor depends on the #ClutterAlignConstraint:align-axis property
|
||||
* and it is a value between 0.0 (meaning left, when
|
||||
* #ClutterAlignConstraint:align-axis is set to %CLUTTER_ALIGN_X_AXIS; or
|
||||
* meaning top, when #ClutterAlignConstraint:align-axis is set to
|
||||
* %CLUTTER_ALIGN_Y_AXIS) and 1.0 (meaning right, when
|
||||
* #ClutterAlignConstraint:align-axis is set to %CLUTTER_ALIGN_X_AXIS; or
|
||||
* meaning bottom, when #ClutterAlignConstraint:align-axis is set to
|
||||
* %CLUTTER_ALIGN_Y_AXIS). A value of 0.5 aligns in the middle in either
|
||||
* cases
|
||||
*/
|
||||
void
|
||||
clutter_align_constraint_set_factor (ClutterAlignConstraint *align,
|
||||
gfloat factor)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
|
||||
|
||||
align->factor = CLAMP (factor, 0.0f, 1.0f);
|
||||
|
||||
if (align->actor != NULL)
|
||||
clutter_actor_queue_relayout (align->actor);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_FACTOR]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_get_factor:
|
||||
* @align: a #ClutterAlignConstraint
|
||||
*
|
||||
* Retrieves the factor set using [method@Clutter.AlignConstraint.set_factor]
|
||||
*
|
||||
* Return value: the alignment factor
|
||||
*/
|
||||
gfloat
|
||||
clutter_align_constraint_get_factor (ClutterAlignConstraint *align)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align), 0.0);
|
||||
|
||||
return align->factor;
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-constraint.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_ALIGN_CONSTRAINT (clutter_align_constraint_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_FINAL_TYPE (ClutterAlignConstraint, clutter_align_constraint,
|
||||
CLUTTER, ALIGN_CONSTRAINT, ClutterConstraint)
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterConstraint *clutter_align_constraint_new (ClutterActor *source,
|
||||
ClutterAlignAxis axis,
|
||||
gfloat factor);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_align_constraint_set_source (ClutterAlignConstraint *align,
|
||||
ClutterActor *source);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_align_constraint_get_source (ClutterAlignConstraint *align);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align,
|
||||
ClutterAlignAxis axis);
|
||||
CLUTTER_EXPORT
|
||||
ClutterAlignAxis clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_align_constraint_set_pivot_point (ClutterAlignConstraint *align,
|
||||
const graphene_point_t *pivot_point);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align,
|
||||
graphene_point_t *pivot_point);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_align_constraint_set_factor (ClutterAlignConstraint *align,
|
||||
gfloat factor);
|
||||
CLUTTER_EXPORT
|
||||
gfloat clutter_align_constraint_get_factor (ClutterAlignConstraint *align);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,207 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2009 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterAnimatable:
|
||||
*
|
||||
* Interface for animatable classes
|
||||
*
|
||||
* #ClutterAnimatable is an interface that allows a [class@GObject.Object] class
|
||||
* to control how an actor will animate a property.
|
||||
*
|
||||
* Each #ClutterAnimatable should implement the
|
||||
* [vfunc@Animatable.interpolate_value] virtual function of the
|
||||
* interface to compute the animation state between two values of an interval
|
||||
* depending on a progress factor, expressed as a floating point value.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-animatable.h"
|
||||
#include "clutter/clutter-interval.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
G_DEFINE_INTERFACE (ClutterAnimatable, clutter_animatable, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
clutter_animatable_default_init (ClutterAnimatableInterface *iface)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_animatable_find_property:
|
||||
* @animatable: a #ClutterAnimatable
|
||||
* @property_name: the name of the animatable property to find
|
||||
*
|
||||
* Finds the [class@GObject.ParamSpec] for @property_name
|
||||
*
|
||||
* Return value: (transfer none): The #GParamSpec for the given property
|
||||
* or %NULL
|
||||
*/
|
||||
GParamSpec *
|
||||
clutter_animatable_find_property (ClutterAnimatable *animatable,
|
||||
const gchar *property_name)
|
||||
{
|
||||
ClutterAnimatableInterface *iface;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), NULL);
|
||||
g_return_val_if_fail (property_name != NULL, NULL);
|
||||
|
||||
CLUTTER_NOTE (ANIMATION, "Looking for property '%s'", property_name);
|
||||
|
||||
iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable);
|
||||
if (iface->find_property != NULL)
|
||||
return iface->find_property (animatable, property_name);
|
||||
|
||||
return g_object_class_find_property (G_OBJECT_GET_CLASS (animatable),
|
||||
property_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_animatable_get_initial_state:
|
||||
* @animatable: a #ClutterAnimatable
|
||||
* @property_name: the name of the animatable property to retrieve
|
||||
* @value: a #GValue initialized to the type of the property to retrieve
|
||||
*
|
||||
* Retrieves the current state of @property_name and sets @value with it
|
||||
*/
|
||||
void
|
||||
clutter_animatable_get_initial_state (ClutterAnimatable *animatable,
|
||||
const gchar *property_name,
|
||||
GValue *value)
|
||||
{
|
||||
ClutterAnimatableInterface *iface;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ANIMATABLE (animatable));
|
||||
g_return_if_fail (property_name != NULL);
|
||||
|
||||
CLUTTER_NOTE (ANIMATION, "Getting initial state of '%s'", property_name);
|
||||
|
||||
iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable);
|
||||
if (iface->get_initial_state != NULL)
|
||||
iface->get_initial_state (animatable, property_name, value);
|
||||
else
|
||||
g_object_get_property (G_OBJECT (animatable), property_name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_animatable_set_final_state:
|
||||
* @animatable: a #ClutterAnimatable
|
||||
* @property_name: the name of the animatable property to set
|
||||
* @value: the value of the animatable property to set
|
||||
*
|
||||
* Sets the current state of @property_name to @value
|
||||
*/
|
||||
void
|
||||
clutter_animatable_set_final_state (ClutterAnimatable *animatable,
|
||||
const gchar *property_name,
|
||||
const GValue *value)
|
||||
{
|
||||
ClutterAnimatableInterface *iface;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ANIMATABLE (animatable));
|
||||
g_return_if_fail (property_name != NULL);
|
||||
|
||||
CLUTTER_NOTE (ANIMATION, "Setting state of property '%s'", property_name);
|
||||
|
||||
iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable);
|
||||
if (iface->set_final_state != NULL)
|
||||
iface->set_final_state (animatable, property_name, value);
|
||||
else
|
||||
g_object_set_property (G_OBJECT (animatable), property_name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_animatable_interpolate_value:
|
||||
* @animatable: a #ClutterAnimatable
|
||||
* @property_name: the name of the property to interpolate
|
||||
* @interval: a #ClutterInterval with the animation range
|
||||
* @progress: the progress to use to interpolate between the
|
||||
* initial and final values of the @interval
|
||||
* @value: (out): return location for an initialized #GValue
|
||||
* using the same type of the @interval
|
||||
*
|
||||
* Asks a #ClutterAnimatable implementation to interpolate a
|
||||
* a named property between the initial and final values of
|
||||
* a #ClutterInterval, using @progress as the interpolation
|
||||
* value, and store the result inside @value.
|
||||
*
|
||||
* This function should be used for every property animation
|
||||
* involving `ClutterAnimatable`s.
|
||||
*
|
||||
* Return value: %TRUE if the interpolation was successful,
|
||||
* and %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
clutter_animatable_interpolate_value (ClutterAnimatable *animatable,
|
||||
const gchar *property_name,
|
||||
ClutterInterval *interval,
|
||||
gdouble progress,
|
||||
GValue *value)
|
||||
{
|
||||
ClutterAnimatableInterface *iface;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), FALSE);
|
||||
g_return_val_if_fail (property_name != NULL, FALSE);
|
||||
g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
CLUTTER_NOTE (ANIMATION, "Interpolating '%s' (progress: %.3f)",
|
||||
property_name,
|
||||
progress);
|
||||
|
||||
iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable);
|
||||
if (iface->interpolate_value != NULL)
|
||||
{
|
||||
return iface->interpolate_value (animatable, property_name,
|
||||
interval,
|
||||
progress,
|
||||
value);
|
||||
}
|
||||
else
|
||||
return clutter_interval_compute_value (interval, progress, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_animatable_get_actor:
|
||||
* @animatable: a #ClutterAnimatable
|
||||
*
|
||||
* Get animated actor.
|
||||
*
|
||||
* Return value: (transfer none): a #ClutterActor
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_animatable_get_actor (ClutterAnimatable *animatable)
|
||||
{
|
||||
ClutterAnimatableInterface *iface;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), NULL);
|
||||
|
||||
iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable);
|
||||
|
||||
g_return_val_if_fail (iface->get_actor, NULL);
|
||||
|
||||
return iface->get_actor (animatable);
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2009 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_ANIMATABLE (clutter_animatable_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_INTERFACE (ClutterAnimatable, clutter_animatable,
|
||||
CLUTTER, ANIMATABLE,
|
||||
GObject)
|
||||
|
||||
/**
|
||||
* ClutterAnimatableInterface:
|
||||
* @find_property: virtual function for retrieving the #GParamSpec of
|
||||
* an animatable property
|
||||
* @get_initial_state: virtual function for retrieving the initial
|
||||
* state of an animatable property
|
||||
* @set_final_state: virtual function for setting the state of an
|
||||
* animatable property
|
||||
* @interpolate_value: virtual function for interpolating the progress
|
||||
* of a property
|
||||
* @get_actor: virtual function for getting associated actor
|
||||
*/
|
||||
struct _ClutterAnimatableInterface
|
||||
{
|
||||
/*< private >*/
|
||||
GTypeInterface parent_iface;
|
||||
|
||||
/*< public >*/
|
||||
GParamSpec *(* find_property) (ClutterAnimatable *animatable,
|
||||
const gchar *property_name);
|
||||
void (* get_initial_state) (ClutterAnimatable *animatable,
|
||||
const gchar *property_name,
|
||||
GValue *value);
|
||||
void (* set_final_state) (ClutterAnimatable *animatable,
|
||||
const gchar *property_name,
|
||||
const GValue *value);
|
||||
gboolean (* interpolate_value) (ClutterAnimatable *animatable,
|
||||
const gchar *property_name,
|
||||
ClutterInterval *interval,
|
||||
gdouble progress,
|
||||
GValue *value);
|
||||
ClutterActor * (* get_actor) (ClutterAnimatable *animatable);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GParamSpec *clutter_animatable_find_property (ClutterAnimatable *animatable,
|
||||
const gchar *property_name);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_animatable_get_initial_state (ClutterAnimatable *animatable,
|
||||
const gchar *property_name,
|
||||
GValue *value);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_animatable_set_final_state (ClutterAnimatable *animatable,
|
||||
const gchar *property_name,
|
||||
const GValue *value);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_animatable_interpolate_value (ClutterAnimatable *animatable,
|
||||
const gchar *property_name,
|
||||
ClutterInterval *interval,
|
||||
gdouble progress,
|
||||
GValue *value);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_animatable_get_actor (ClutterAnimatable *animatable);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef HAVE_FONTS
|
||||
#include <cairo.h>
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-backend.h"
|
||||
#include "clutter/clutter-seat.h"
|
||||
#include "clutter/clutter-stage-window.h"
|
||||
|
||||
#define CLUTTER_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BACKEND, ClutterBackendClass))
|
||||
#define CLUTTER_IS_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BACKEND))
|
||||
#define CLUTTER_BACKEND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BACKEND, ClutterBackendClass))
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _ClutterBackendPrivate ClutterBackendPrivate;
|
||||
|
||||
struct _ClutterBackend
|
||||
{
|
||||
/*< private >*/
|
||||
GObject parent_instance;
|
||||
|
||||
ClutterContext *context;
|
||||
|
||||
CoglRenderer *cogl_renderer;
|
||||
CoglDisplay *cogl_display;
|
||||
CoglContext *cogl_context;
|
||||
GSource *cogl_source;
|
||||
|
||||
CoglOnscreen *dummy_onscreen;
|
||||
|
||||
#ifdef HAVE_FONTS
|
||||
cairo_font_options_t *font_options;
|
||||
#endif
|
||||
|
||||
float fallback_resource_scale;
|
||||
|
||||
ClutterStageWindow *stage_window;
|
||||
|
||||
ClutterInputMethod *input_method;
|
||||
};
|
||||
|
||||
struct _ClutterBackendClass
|
||||
{
|
||||
/*< private >*/
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* vfuncs */
|
||||
ClutterStageWindow * (* create_stage) (ClutterBackend *backend,
|
||||
ClutterStage *wrapper,
|
||||
GError **error);
|
||||
CoglRenderer * (* get_renderer) (ClutterBackend *backend,
|
||||
GError **error);
|
||||
gboolean (* create_context) (ClutterBackend *backend,
|
||||
GError **error);
|
||||
|
||||
ClutterSeat * (* get_default_seat) (ClutterBackend *backend);
|
||||
|
||||
gboolean (* is_display_server) (ClutterBackend *backend);
|
||||
|
||||
/* signals */
|
||||
void (* resolution_changed) (ClutterBackend *backend);
|
||||
};
|
||||
|
||||
ClutterStageWindow * _clutter_backend_create_stage (ClutterBackend *backend,
|
||||
ClutterStage *wrapper,
|
||||
GError **error);
|
||||
gboolean _clutter_backend_create_context (ClutterBackend *backend,
|
||||
GError **error);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterStageWindow * clutter_backend_get_stage_window (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_backend_set_fallback_resource_scale (ClutterBackend *backend,
|
||||
float fallback_resource_scale);
|
||||
|
||||
float clutter_backend_get_fallback_resource_scale (ClutterBackend *backend);
|
||||
|
||||
gboolean clutter_backend_is_display_server (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_backend_destroy (ClutterBackend *backend);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,578 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By:
|
||||
* Matthew Allum <mallum@openedhand.com>
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*
|
||||
* Copyright (C) 2006, 2007, 2008 OpenedHand Ltd
|
||||
* Copyright (C) 2009, 2010 Intel Corp
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterBackend:
|
||||
*
|
||||
* Backend abstraction
|
||||
*
|
||||
* Clutter can be compiled against different backends. Each backend
|
||||
* has to implement a set of functions, in order to be used by Clutter.
|
||||
*
|
||||
* #ClutterBackend is the base class abstracting the various implementation;
|
||||
* it provides a basic API to query the backend for generic information
|
||||
* and settings.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_FONTS
|
||||
#include <cairo.h>
|
||||
#include <pango/pangocairo.h>
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-backend-private.h"
|
||||
#include "clutter/clutter-context-private.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-event-private.h"
|
||||
#include "clutter/clutter-marshal.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#include "clutter/clutter-stage-manager-private.h"
|
||||
#include "clutter/clutter-stage-private.h"
|
||||
#include "clutter/clutter-stage-window.h"
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
|
||||
enum
|
||||
{
|
||||
RESOLUTION_CHANGED,
|
||||
FONT_CHANGED,
|
||||
SETTINGS_CHANGED,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_CONTEXT,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *pspecs[N_PROPS] = { 0 };
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (ClutterBackend, clutter_backend, G_TYPE_OBJECT)
|
||||
|
||||
static guint backend_signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
static void
|
||||
clutter_backend_dispose (GObject *gobject)
|
||||
{
|
||||
ClutterBackend *backend = CLUTTER_BACKEND (gobject);
|
||||
|
||||
/* clear the events still in the queue of the main context */
|
||||
_clutter_clear_events_queue ();
|
||||
|
||||
g_clear_object (&backend->dummy_onscreen);
|
||||
if (backend->stage_window)
|
||||
{
|
||||
g_object_remove_weak_pointer (G_OBJECT (backend->stage_window),
|
||||
(gpointer *) &backend->stage_window);
|
||||
backend->stage_window = NULL;
|
||||
}
|
||||
|
||||
g_clear_pointer (&backend->cogl_source, g_source_destroy);
|
||||
#ifdef HAVE_FONTS
|
||||
g_clear_pointer (&backend->font_options, cairo_font_options_destroy);
|
||||
#endif
|
||||
g_clear_object (&backend->input_method);
|
||||
|
||||
G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_backend_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterBackend *backend = CLUTTER_BACKEND (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTEXT:
|
||||
g_value_set_object (value, backend->context);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_backend_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterBackend *backend = CLUTTER_BACKEND (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTEXT:
|
||||
backend->context = g_value_get_object (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_FONTS
|
||||
static void
|
||||
clutter_backend_real_resolution_changed (ClutterBackend *backend)
|
||||
{
|
||||
ClutterContext *context = backend->context;
|
||||
ClutterSettings *settings = clutter_context_get_settings (context);
|
||||
gdouble resolution;
|
||||
gint dpi;
|
||||
|
||||
g_object_get (settings, "font-dpi", &dpi, NULL);
|
||||
|
||||
if (dpi < 0)
|
||||
resolution = 96.0;
|
||||
else
|
||||
resolution = dpi / 1024.0;
|
||||
|
||||
if (context->font_map != NULL)
|
||||
pango_cairo_font_map_set_resolution (PANGO_CAIRO_FONT_MAP (context->font_map),
|
||||
resolution);
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
clutter_backend_do_real_create_context (ClutterBackend *backend,
|
||||
CoglDriverId driver_id,
|
||||
GError **error)
|
||||
{
|
||||
ClutterBackendClass *klass;
|
||||
|
||||
cogl_init ();
|
||||
|
||||
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
||||
CLUTTER_NOTE (BACKEND, "Creating Cogl renderer");
|
||||
backend->cogl_renderer = klass->get_renderer (backend, error);
|
||||
|
||||
if (backend->cogl_renderer == NULL)
|
||||
goto error;
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Connecting the renderer");
|
||||
cogl_renderer_set_driver (backend->cogl_renderer, driver_id);
|
||||
if (!cogl_renderer_connect (backend->cogl_renderer, error))
|
||||
goto error;
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Creating Cogl display");
|
||||
backend->cogl_display = cogl_display_new (backend->cogl_renderer);
|
||||
|
||||
if (backend->cogl_display == NULL)
|
||||
goto error;
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Setting up the display");
|
||||
if (!cogl_display_setup (backend->cogl_display, error))
|
||||
goto error;
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Creating the Cogl context");
|
||||
backend->cogl_context = cogl_context_new (backend->cogl_display, error);
|
||||
if (backend->cogl_context == NULL)
|
||||
goto error;
|
||||
|
||||
/* the display owns the renderer and the swap chain */
|
||||
g_object_unref (backend->cogl_renderer);
|
||||
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
g_clear_object (&backend->cogl_display);
|
||||
g_clear_object (&backend->cogl_renderer);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *driver_name;
|
||||
const char *driver_desc;
|
||||
CoglDriverId driver_id;
|
||||
} all_known_drivers[] = {
|
||||
{ "gl3", "OpenGL 3.1 core profile", COGL_DRIVER_ID_GL3 },
|
||||
{ "gles2", "OpenGL ES 2.0", COGL_DRIVER_ID_GLES2 },
|
||||
{ "any", "Default Cogl driver", COGL_DRIVER_ID_ANY },
|
||||
};
|
||||
|
||||
static gboolean
|
||||
clutter_backend_real_create_context (ClutterBackend *backend,
|
||||
GError **error)
|
||||
{
|
||||
GError *internal_error = NULL;
|
||||
const char *drivers_list;
|
||||
char **known_drivers;
|
||||
int i;
|
||||
|
||||
if (backend->cogl_context != NULL)
|
||||
return TRUE;
|
||||
|
||||
drivers_list = g_getenv ("CLUTTER_DRIVER");
|
||||
if (drivers_list == NULL)
|
||||
drivers_list = "*";
|
||||
|
||||
known_drivers = g_strsplit (drivers_list, ",", 0);
|
||||
|
||||
for (i = 0; backend->cogl_context == NULL && known_drivers[i] != NULL; i++)
|
||||
{
|
||||
const char *driver_name = known_drivers[i];
|
||||
gboolean is_any = g_str_equal (driver_name, "*");
|
||||
int j;
|
||||
|
||||
for (j = 0; j < G_N_ELEMENTS (all_known_drivers); j++)
|
||||
{
|
||||
if (is_any ||
|
||||
g_str_equal (all_known_drivers[j].driver_name, driver_name))
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND, "Checking for the %s driver", all_known_drivers[j].driver_desc);
|
||||
|
||||
if (clutter_backend_do_real_create_context (backend, all_known_drivers[j].driver_id, &internal_error))
|
||||
break;
|
||||
|
||||
if (internal_error)
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND, "Unable to use the %s driver: %s",
|
||||
all_known_drivers[j].driver_desc,
|
||||
internal_error->message);
|
||||
g_clear_error (&internal_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev (known_drivers);
|
||||
|
||||
if (backend->cogl_context == NULL)
|
||||
{
|
||||
if (internal_error != NULL)
|
||||
g_propagate_error (error, internal_error);
|
||||
else
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Unable to initialize the Clutter backend: no available drivers found.");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
backend->cogl_source = cogl_glib_source_new (backend->cogl_renderer, G_PRIORITY_DEFAULT);
|
||||
g_source_attach (backend->cogl_source, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_backend_class_init (ClutterBackendClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->dispose = clutter_backend_dispose;
|
||||
gobject_class->get_property = clutter_backend_get_property;
|
||||
gobject_class->set_property = clutter_backend_set_property;
|
||||
|
||||
/**
|
||||
* ClutterBackend::resolution-changed:
|
||||
* @backend: the #ClutterBackend that emitted the signal
|
||||
*
|
||||
* The signal is emitted each time the font
|
||||
* resolutions has been changed through #ClutterSettings.
|
||||
*/
|
||||
backend_signals[RESOLUTION_CHANGED] =
|
||||
g_signal_new (I_("resolution-changed"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterBackendClass, resolution_changed),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* ClutterBackend::font-changed:
|
||||
* @backend: the #ClutterBackend that emitted the signal
|
||||
*
|
||||
* The signal is emitted each time the font options
|
||||
* have been changed through #ClutterSettings.
|
||||
*/
|
||||
backend_signals[FONT_CHANGED] =
|
||||
g_signal_new (I_("font-changed"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* ClutterBackend::settings-changed:
|
||||
* @backend: the #ClutterBackend that emitted the signal
|
||||
*
|
||||
* The signal is emitted each time the #ClutterSettings
|
||||
* properties have been changed.
|
||||
*/
|
||||
backend_signals[SETTINGS_CHANGED] =
|
||||
g_signal_new (I_("settings-changed"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
pspecs[PROP_CONTEXT] =
|
||||
g_param_spec_object ("context", NULL, NULL,
|
||||
CLUTTER_TYPE_CONTEXT,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPS, pspecs);
|
||||
|
||||
#ifdef HAVE_FONTS
|
||||
klass->resolution_changed = clutter_backend_real_resolution_changed;
|
||||
#endif
|
||||
|
||||
klass->create_context = clutter_backend_real_create_context;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_backend_init (ClutterBackend *self)
|
||||
{
|
||||
self->dummy_onscreen = NULL;
|
||||
|
||||
self->fallback_resource_scale = 1.f;
|
||||
|
||||
/* Default font options */
|
||||
#ifdef HAVE_FONTS
|
||||
self->font_options = cairo_font_options_create ();
|
||||
cairo_font_options_set_hint_metrics (self->font_options,
|
||||
CAIRO_HINT_METRICS_ON);
|
||||
cairo_font_options_set_hint_style (self->font_options,
|
||||
CAIRO_HINT_STYLE_NONE);
|
||||
cairo_font_options_set_subpixel_order (self->font_options,
|
||||
CAIRO_SUBPIXEL_ORDER_DEFAULT);
|
||||
cairo_font_options_set_antialias (self->font_options,
|
||||
CAIRO_ANTIALIAS_DEFAULT);
|
||||
#endif
|
||||
}
|
||||
|
||||
ClutterStageWindow *
|
||||
_clutter_backend_create_stage (ClutterBackend *backend,
|
||||
ClutterStage *wrapper,
|
||||
GError **error)
|
||||
{
|
||||
ClutterBackendClass *klass;
|
||||
ClutterStageWindow *stage_window;
|
||||
|
||||
g_assert (CLUTTER_IS_BACKEND (backend));
|
||||
g_assert (CLUTTER_IS_STAGE (wrapper));
|
||||
|
||||
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
||||
if (klass->create_stage != NULL)
|
||||
stage_window = klass->create_stage (backend, wrapper, error);
|
||||
else
|
||||
stage_window = NULL;
|
||||
|
||||
if (stage_window == NULL)
|
||||
return NULL;
|
||||
|
||||
g_assert (CLUTTER_IS_STAGE_WINDOW (stage_window));
|
||||
|
||||
backend->stage_window = stage_window;
|
||||
g_object_add_weak_pointer (G_OBJECT (backend->stage_window),
|
||||
(gpointer *) &backend->stage_window);
|
||||
|
||||
return stage_window;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_backend_create_context (ClutterBackend *backend,
|
||||
GError **error)
|
||||
{
|
||||
ClutterBackendClass *klass;
|
||||
|
||||
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
||||
|
||||
return klass->create_context (backend, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_get_default_backend:
|
||||
*
|
||||
* Retrieves the default #ClutterBackend used by Clutter. The
|
||||
* #ClutterBackend holds backend-specific configuration options.
|
||||
*
|
||||
* Return value: (transfer none): the default backend. You should
|
||||
* not ref or unref the returned object. Applications should rarely
|
||||
* need to use this.
|
||||
*/
|
||||
ClutterBackend *
|
||||
clutter_get_default_backend (void)
|
||||
{
|
||||
ClutterContext *clutter_context;
|
||||
|
||||
clutter_context = _clutter_context_get_default ();
|
||||
|
||||
return clutter_context->backend;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_backend_get_resolution:
|
||||
* @backend: a #ClutterBackend
|
||||
*
|
||||
* Gets the resolution for font handling on the screen.
|
||||
*
|
||||
* The resolution is a scale factor between points specified in a
|
||||
* #PangoFontDescription and cairo units. The default value is 96.0,
|
||||
* meaning that a 10 point font will be 13 units
|
||||
* high (10 * 96. / 72. = 13.3).
|
||||
*
|
||||
* Clutter will set the resolution using the current backend when
|
||||
* initializing; the resolution is also stored in the
|
||||
* #ClutterSettings:font-dpi property.
|
||||
*
|
||||
* Return value: the current resolution, or -1 if no resolution
|
||||
* has been set.
|
||||
*/
|
||||
gdouble
|
||||
clutter_backend_get_resolution (ClutterBackend *backend)
|
||||
{
|
||||
ClutterSettings *settings;
|
||||
gint resolution;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), -1.0);
|
||||
|
||||
settings = clutter_context_get_settings (backend->context);
|
||||
g_object_get (settings, "font-dpi", &resolution, NULL);
|
||||
|
||||
if (resolution < 0)
|
||||
return 96.0;
|
||||
|
||||
return resolution / 1024.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_backend_get_cogl_context:
|
||||
* @backend: a #ClutterBackend
|
||||
*
|
||||
* Retrieves the #CoglContext associated with the given clutter
|
||||
* @backend. A #CoglContext is required when using some of the
|
||||
* experimental 2.0 Cogl API.
|
||||
*
|
||||
* Since CoglContext is itself experimental API this API should
|
||||
* be considered experimental too.
|
||||
*
|
||||
* This API is not yet supported on OSX because OSX still
|
||||
* uses the stub Cogl winsys and the Clutter backend doesn't
|
||||
* explicitly create a CoglContext.
|
||||
*
|
||||
* Return value: (transfer none): The #CoglContext associated with @backend.
|
||||
*/
|
||||
CoglContext *
|
||||
clutter_backend_get_cogl_context (ClutterBackend *backend)
|
||||
{
|
||||
return backend->cogl_context;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_backend_get_input_method:
|
||||
* @backend: the #CLutterBackend
|
||||
*
|
||||
* Returns the input method used by Clutter
|
||||
*
|
||||
* Returns: (transfer none): the input method
|
||||
**/
|
||||
ClutterInputMethod *
|
||||
clutter_backend_get_input_method (ClutterBackend *backend)
|
||||
{
|
||||
return backend->input_method;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_backend_set_input_method:
|
||||
* @backend: the #ClutterBackend
|
||||
* @method: (nullable): the input method
|
||||
*
|
||||
* Sets the input method to be used by Clutter
|
||||
**/
|
||||
void
|
||||
clutter_backend_set_input_method (ClutterBackend *backend,
|
||||
ClutterInputMethod *method)
|
||||
{
|
||||
if (backend->input_method == method)
|
||||
return;
|
||||
|
||||
if (backend->input_method)
|
||||
clutter_input_method_focus_out (backend->input_method);
|
||||
|
||||
g_set_object (&backend->input_method, method);
|
||||
}
|
||||
|
||||
ClutterStageWindow *
|
||||
clutter_backend_get_stage_window (ClutterBackend *backend)
|
||||
{
|
||||
return backend->stage_window;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_backend_get_default_seat:
|
||||
* @backend: the #ClutterBackend
|
||||
*
|
||||
* Returns the default seat
|
||||
*
|
||||
* Returns: (transfer none): the default seat
|
||||
**/
|
||||
ClutterSeat *
|
||||
clutter_backend_get_default_seat (ClutterBackend *backend)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), NULL);
|
||||
|
||||
return CLUTTER_BACKEND_GET_CLASS (backend)->get_default_seat (backend);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_backend_set_fallback_resource_scale (ClutterBackend *backend,
|
||||
float fallback_resource_scale)
|
||||
{
|
||||
backend->fallback_resource_scale = fallback_resource_scale;
|
||||
}
|
||||
|
||||
float
|
||||
clutter_backend_get_fallback_resource_scale (ClutterBackend *backend)
|
||||
{
|
||||
return backend->fallback_resource_scale;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_backend_is_display_server (ClutterBackend *backend)
|
||||
{
|
||||
return CLUTTER_BACKEND_GET_CLASS (backend)->is_display_server (backend);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_backend_destroy (ClutterBackend *backend)
|
||||
{
|
||||
g_object_run_dispose (G_OBJECT (backend));
|
||||
g_object_unref (backend);
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2006 OpenedHand
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
|
||||
#include "clutter/clutter-keymap.h"
|
||||
#include "clutter/clutter-types.h"
|
||||
#include "clutter/clutter-seat.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_BACKEND (clutter_backend_get_type ())
|
||||
#define CLUTTER_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BACKEND, ClutterBackend))
|
||||
#define CLUTTER_IS_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BACKEND))
|
||||
|
||||
typedef struct _ClutterBackend ClutterBackend;
|
||||
typedef struct _ClutterBackendClass ClutterBackendClass;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_backend_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterBackend * clutter_get_default_backend (void);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gdouble clutter_backend_get_resolution (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
CoglContext * clutter_backend_get_cogl_context (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterInputMethod * clutter_backend_get_input_method (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_backend_set_input_method (ClutterBackend *backend,
|
||||
ClutterInputMethod *method);
|
||||
CLUTTER_EXPORT
|
||||
ClutterSeat * clutter_backend_get_default_seat (ClutterBackend *backend);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackend, g_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2006 OpenedHand
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define FLOAT_EPSILON (1e-15)
|
||||
|
||||
/*
|
||||
* ClutterMargin
|
||||
*/
|
||||
|
||||
/**
|
||||
* clutter_margin_new:
|
||||
*
|
||||
* Creates a new #ClutterMargin.
|
||||
*
|
||||
* Return value: (transfer full): a newly allocated #ClutterMargin. Use
|
||||
* [method@Clutter.Margin.free] to free the resources associated with it when
|
||||
* done.
|
||||
*/
|
||||
ClutterMargin *
|
||||
clutter_margin_new (void)
|
||||
{
|
||||
return g_new0 (ClutterMargin, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_margin_copy:
|
||||
* @margin_: a #ClutterMargin
|
||||
*
|
||||
* Creates a new #ClutterMargin and copies the contents of @margin_ into
|
||||
* the newly created structure.
|
||||
*
|
||||
* Return value: (transfer full): a copy of the #ClutterMargin.
|
||||
*/
|
||||
ClutterMargin *
|
||||
clutter_margin_copy (const ClutterMargin *margin_)
|
||||
{
|
||||
if (G_LIKELY (margin_ != NULL))
|
||||
return g_memdup2 (margin_, sizeof (ClutterMargin));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_margin_free:
|
||||
* @margin_: a #ClutterMargin
|
||||
*
|
||||
* Frees the resources allocated by [ctor@Clutter.Margin.new] and
|
||||
* [method@Clutter.Margin.copy].
|
||||
*/
|
||||
void
|
||||
clutter_margin_free (ClutterMargin *margin_)
|
||||
{
|
||||
if (G_LIKELY (margin_ != NULL))
|
||||
g_free (margin_);
|
||||
}
|
||||
|
||||
G_DEFINE_BOXED_TYPE (ClutterMargin, clutter_margin,
|
||||
clutter_margin_copy,
|
||||
clutter_margin_free)
|
||||
@@ -1,279 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2009 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterBinLayout:
|
||||
*
|
||||
* A simple layout manager
|
||||
*
|
||||
* #ClutterBinLayout is a layout manager which implements the following
|
||||
* policy:
|
||||
*
|
||||
* - the preferred size is the maximum preferred size
|
||||
* between all the children of the container using the
|
||||
* layout;
|
||||
* - each child is allocated in "layers", on on top
|
||||
* of the other;
|
||||
* - for each layer there are horizontal and vertical
|
||||
* alignment policies.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "clutter/clutter-actor-private.h"
|
||||
#include "clutter/clutter-animatable.h"
|
||||
#include "clutter/clutter-bin-layout.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-enum-types.h"
|
||||
#include "clutter/clutter-layout-meta.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
G_DEFINE_TYPE (ClutterBinLayout,
|
||||
clutter_bin_layout,
|
||||
CLUTTER_TYPE_LAYOUT_MANAGER)
|
||||
|
||||
static void
|
||||
clutter_bin_layout_get_preferred_width (ClutterLayoutManager *manager,
|
||||
ClutterActor *container,
|
||||
gfloat for_height,
|
||||
gfloat *min_width_p,
|
||||
gfloat *nat_width_p)
|
||||
{
|
||||
ClutterActor *actor = CLUTTER_ACTOR (container);
|
||||
ClutterActorIter iter;
|
||||
ClutterActor *child;
|
||||
gfloat min_width, nat_width;
|
||||
|
||||
min_width = nat_width = 0.0;
|
||||
|
||||
clutter_actor_iter_init (&iter, actor);
|
||||
while (clutter_actor_iter_next (&iter, &child))
|
||||
{
|
||||
gfloat minimum, natural;
|
||||
|
||||
if (!clutter_actor_is_visible (child))
|
||||
continue;
|
||||
|
||||
clutter_actor_get_preferred_width (child, for_height,
|
||||
&minimum,
|
||||
&natural);
|
||||
|
||||
min_width = MAX (min_width, minimum);
|
||||
nat_width = MAX (nat_width, natural);
|
||||
}
|
||||
|
||||
if (min_width_p)
|
||||
*min_width_p = min_width;
|
||||
|
||||
if (nat_width_p)
|
||||
*nat_width_p = nat_width;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bin_layout_get_preferred_height (ClutterLayoutManager *manager,
|
||||
ClutterActor *container,
|
||||
gfloat for_width,
|
||||
gfloat *min_height_p,
|
||||
gfloat *nat_height_p)
|
||||
{
|
||||
ClutterActor *actor = CLUTTER_ACTOR (container);
|
||||
ClutterActorIter iter;
|
||||
ClutterActor *child;
|
||||
gfloat min_height, nat_height;
|
||||
|
||||
min_height = nat_height = 0.0;
|
||||
|
||||
clutter_actor_iter_init (&iter, actor);
|
||||
while (clutter_actor_iter_next (&iter, &child))
|
||||
{
|
||||
gfloat minimum, natural;
|
||||
|
||||
if (!clutter_actor_is_visible (child))
|
||||
continue;
|
||||
|
||||
clutter_actor_get_preferred_height (child, for_width,
|
||||
&minimum,
|
||||
&natural);
|
||||
|
||||
min_height = MAX (min_height, minimum);
|
||||
nat_height = MAX (nat_height, natural);
|
||||
}
|
||||
|
||||
if (min_height_p)
|
||||
*min_height_p = min_height;
|
||||
|
||||
if (nat_height_p)
|
||||
*nat_height_p = nat_height;
|
||||
}
|
||||
|
||||
static gdouble
|
||||
get_actor_align_factor (ClutterActorAlign alignment)
|
||||
{
|
||||
switch (alignment)
|
||||
{
|
||||
case CLUTTER_ACTOR_ALIGN_CENTER:
|
||||
return 0.5;
|
||||
|
||||
case CLUTTER_ACTOR_ALIGN_START:
|
||||
return 0.0;
|
||||
|
||||
case CLUTTER_ACTOR_ALIGN_END:
|
||||
return 1.0;
|
||||
|
||||
case CLUTTER_ACTOR_ALIGN_FILL:
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bin_layout_allocate (ClutterLayoutManager *manager,
|
||||
ClutterActor *container,
|
||||
const ClutterActorBox *allocation)
|
||||
{
|
||||
gfloat allocation_x, allocation_y;
|
||||
gfloat available_w, available_h;
|
||||
ClutterActor *actor, *child;
|
||||
ClutterActorIter iter;
|
||||
|
||||
clutter_actor_box_get_origin (allocation, &allocation_x, &allocation_y);
|
||||
clutter_actor_box_get_size (allocation, &available_w, &available_h);
|
||||
|
||||
actor = CLUTTER_ACTOR (container);
|
||||
|
||||
clutter_actor_iter_init (&iter, actor);
|
||||
while (clutter_actor_iter_next (&iter, &child))
|
||||
{
|
||||
ClutterActorBox child_alloc = { 0, };
|
||||
gdouble x_align, y_align;
|
||||
gboolean x_fill, y_fill, is_fixed_position_set;
|
||||
float fixed_x, fixed_y;
|
||||
|
||||
if (!clutter_actor_is_visible (child))
|
||||
continue;
|
||||
|
||||
fixed_x = fixed_y = 0.f;
|
||||
g_object_get (child,
|
||||
"fixed-position-set", &is_fixed_position_set,
|
||||
"fixed-x", &fixed_x,
|
||||
"fixed-y", &fixed_y,
|
||||
NULL);
|
||||
|
||||
if (is_fixed_position_set)
|
||||
{
|
||||
if (is_fixed_position_set)
|
||||
child_alloc.x1 = fixed_x;
|
||||
else
|
||||
child_alloc.x1 = clutter_actor_get_x (child);
|
||||
}
|
||||
else
|
||||
child_alloc.x1 = allocation_x;
|
||||
|
||||
if (is_fixed_position_set)
|
||||
{
|
||||
if (is_fixed_position_set)
|
||||
child_alloc.y1 = fixed_y;
|
||||
else
|
||||
child_alloc.y1 = clutter_actor_get_y (child);
|
||||
}
|
||||
else
|
||||
child_alloc.y1 = allocation_y;
|
||||
|
||||
child_alloc.x2 = allocation_x + available_w;
|
||||
child_alloc.y2 = allocation_y + available_h;
|
||||
|
||||
if (clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_HORIZONTAL))
|
||||
{
|
||||
ClutterActorAlign align;
|
||||
|
||||
align = clutter_actor_get_x_align (child);
|
||||
x_fill = align == CLUTTER_ACTOR_ALIGN_FILL;
|
||||
x_align = get_actor_align_factor (align);
|
||||
}
|
||||
else
|
||||
{
|
||||
x_fill = FALSE;
|
||||
|
||||
if (!is_fixed_position_set)
|
||||
x_align = 0.5;
|
||||
else
|
||||
x_align = 0.0;
|
||||
}
|
||||
|
||||
if (clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_VERTICAL))
|
||||
{
|
||||
ClutterActorAlign align;
|
||||
|
||||
align = clutter_actor_get_y_align (child);
|
||||
y_fill = align == CLUTTER_ACTOR_ALIGN_FILL;
|
||||
y_align = get_actor_align_factor (align);
|
||||
}
|
||||
else
|
||||
{
|
||||
y_fill = FALSE;
|
||||
|
||||
if (!is_fixed_position_set)
|
||||
y_align = 0.5;
|
||||
else
|
||||
y_align = 0.0;
|
||||
}
|
||||
|
||||
clutter_actor_allocate_align_fill (child, &child_alloc,
|
||||
x_align, y_align,
|
||||
x_fill, y_fill);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bin_layout_class_init (ClutterBinLayoutClass *klass)
|
||||
{
|
||||
ClutterLayoutManagerClass *layout_class =
|
||||
CLUTTER_LAYOUT_MANAGER_CLASS (klass);
|
||||
|
||||
layout_class->get_preferred_width = clutter_bin_layout_get_preferred_width;
|
||||
layout_class->get_preferred_height = clutter_bin_layout_get_preferred_height;
|
||||
layout_class->allocate = clutter_bin_layout_allocate;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bin_layout_init (ClutterBinLayout *self)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_bin_layout_new:
|
||||
*
|
||||
* Creates a new #ClutterBinLayout layout manager
|
||||
*
|
||||
* Return value: the newly created layout manager
|
||||
*/
|
||||
ClutterLayoutManager *
|
||||
clutter_bin_layout_new (void)
|
||||
{
|
||||
return g_object_new (CLUTTER_TYPE_BIN_LAYOUT,
|
||||
NULL);
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2009 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-layout-manager.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_BIN_LAYOUT (clutter_bin_layout_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterBinLayout,
|
||||
clutter_bin_layout,
|
||||
CLUTTER,
|
||||
BIN_LAYOUT,
|
||||
ClutterLayoutManager)
|
||||
|
||||
/**
|
||||
* ClutterBinLayoutClass:
|
||||
*
|
||||
* The #ClutterBinLayoutClass structure contains only private
|
||||
* data and should be accessed using the provided API
|
||||
*/
|
||||
struct _ClutterBinLayoutClass
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterLayoutManagerClass parent_class;
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterLayoutManager * clutter_bin_layout_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,617 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterBindConstraint:
|
||||
*
|
||||
* A constraint binding the position or size of an actor
|
||||
*
|
||||
* #ClutterBindConstraint is a [class@Constraint] that binds the
|
||||
* position or the size of the [class@Actor] to which it is applied
|
||||
* to the the position or the size of another [class@Actor], or
|
||||
* "source".
|
||||
*
|
||||
* An offset can be applied to the constraint, to avoid overlapping. The offset
|
||||
* can also be animated. For instance, the following code will set up three
|
||||
* actors to be bound to the same origin:
|
||||
*
|
||||
* ```c
|
||||
* // source
|
||||
* rect[0] = clutter_actor_new ();
|
||||
* clutter_actor_set_background_color (rect[0], &red_color);
|
||||
* clutter_actor_set_position (rect[0], x_pos, y_pos);
|
||||
* clutter_actor_set_size (rect[0], 100, 100);
|
||||
*
|
||||
* // second rectangle
|
||||
* rect[1] = clutter_actor_new ();
|
||||
* clutter_actor_set_background_color (rect[1], &green_color);
|
||||
* clutter_actor_set_size (rect[1], 100, 100);
|
||||
* clutter_actor_set_opacity (rect[1], 0);
|
||||
*
|
||||
* constraint = clutter_bind_constraint_new (rect[0], CLUTTER_BIND_X, 0.0);
|
||||
* clutter_actor_add_constraint_with_name (rect[1], "green-x", constraint);
|
||||
* constraint = clutter_bind_constraint_new (rect[0], CLUTTER_BIND_Y, 0.0);
|
||||
* clutter_actor_add_constraint_with_name (rect[1], "green-y", constraint);
|
||||
*
|
||||
* // third rectangle
|
||||
* rect[2] = clutter_actor_new ();
|
||||
* clutter_actor_set_background_color (rect[2], &blue_color);
|
||||
* clutter_actor_set_size (rect[2], 100, 100);
|
||||
* clutter_actor_set_opacity (rect[2], 0);
|
||||
*
|
||||
* constraint = clutter_bind_constraint_new (rect[0], CLUTTER_BIND_X, 0.0);
|
||||
* clutter_actor_add_constraint_with_name (rect[2], "blue-x", constraint);
|
||||
* constraint = clutter_bind_constraint_new (rect[0], CLUTTER_BIND_Y, 0.0);
|
||||
* clutter_actor_add_constraint_with_name (rect[2], "blue-y", constraint);
|
||||
* ```
|
||||
*
|
||||
* The following code animates the second and third rectangles to "expand"
|
||||
* them horizontally from underneath the first rectangle:
|
||||
*
|
||||
* ```c
|
||||
* clutter_actor_animate (rect[1], CLUTTER_EASE_OUT_CUBIC, 250,
|
||||
* "@constraints.green-x.offset", 100.0,
|
||||
* "opacity", 255,
|
||||
* NULL);
|
||||
* clutter_actor_animate (rect[2], CLUTTER_EASE_OUT_CUBIC, 250,
|
||||
* "@constraints.blue-x.offset", 200.0,
|
||||
* "opacity", 255,
|
||||
* NULL);
|
||||
* ```
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "clutter/clutter-bind-constraint.h"
|
||||
|
||||
#include "clutter/clutter-actor-meta-private.h"
|
||||
#include "clutter/clutter-actor-private.h"
|
||||
#include "clutter/clutter-constraint.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-enum-types.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
struct _ClutterBindConstraint
|
||||
{
|
||||
ClutterConstraint parent_instance;
|
||||
|
||||
ClutterActor *actor;
|
||||
ClutterActor *source;
|
||||
ClutterBindCoordinate coordinate;
|
||||
gfloat offset;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_SOURCE,
|
||||
PROP_COORDINATE,
|
||||
PROP_OFFSET,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
G_DEFINE_FINAL_TYPE (ClutterBindConstraint,
|
||||
clutter_bind_constraint,
|
||||
CLUTTER_TYPE_CONSTRAINT);
|
||||
|
||||
static void
|
||||
source_queue_relayout (ClutterActor *source,
|
||||
ClutterBindConstraint *bind)
|
||||
{
|
||||
if (bind->actor != NULL)
|
||||
_clutter_actor_queue_only_relayout (bind->actor);
|
||||
}
|
||||
|
||||
static void
|
||||
source_destroyed (ClutterActor *actor,
|
||||
ClutterBindConstraint *bind)
|
||||
{
|
||||
bind->source = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bind_constraint_update_preferred_size (ClutterConstraint *constraint,
|
||||
ClutterActor *actor,
|
||||
ClutterOrientation direction,
|
||||
float for_size,
|
||||
float *minimum_size,
|
||||
float *natural_size)
|
||||
{
|
||||
ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint);
|
||||
float source_min, source_nat;
|
||||
|
||||
if (bind->source == NULL)
|
||||
return;
|
||||
|
||||
/* only these bindings affect the preferred size */
|
||||
if (!(bind->coordinate == CLUTTER_BIND_WIDTH ||
|
||||
bind->coordinate == CLUTTER_BIND_HEIGHT ||
|
||||
bind->coordinate == CLUTTER_BIND_SIZE ||
|
||||
bind->coordinate == CLUTTER_BIND_ALL))
|
||||
return;
|
||||
|
||||
if (clutter_actor_contains (bind->source, actor))
|
||||
return;
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case CLUTTER_ORIENTATION_HORIZONTAL:
|
||||
if (bind->coordinate != CLUTTER_BIND_HEIGHT)
|
||||
{
|
||||
clutter_actor_get_preferred_width (bind->source, for_size,
|
||||
&source_min,
|
||||
&source_nat);
|
||||
|
||||
*minimum_size = source_min;
|
||||
*natural_size = source_nat;
|
||||
}
|
||||
break;
|
||||
|
||||
case CLUTTER_ORIENTATION_VERTICAL:
|
||||
if (bind->coordinate != CLUTTER_BIND_WIDTH)
|
||||
{
|
||||
clutter_actor_get_preferred_height (bind->source, for_size,
|
||||
&source_min,
|
||||
&source_nat);
|
||||
|
||||
*minimum_size = source_min;
|
||||
*natural_size = source_nat;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bind_constraint_update_allocation (ClutterConstraint *constraint,
|
||||
ClutterActor *actor,
|
||||
ClutterActorBox *allocation)
|
||||
{
|
||||
ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint);
|
||||
gfloat source_width, source_height;
|
||||
gfloat actor_width, actor_height;
|
||||
graphene_point3d_t source_position;
|
||||
|
||||
source_position = GRAPHENE_POINT3D_INIT (0.f, 0.f, 0.f);
|
||||
|
||||
if (bind->source == NULL)
|
||||
return;
|
||||
|
||||
source_position.x = clutter_actor_get_x (bind->source);
|
||||
source_position.y = clutter_actor_get_y (bind->source);
|
||||
clutter_actor_get_size (bind->source, &source_width, &source_height);
|
||||
|
||||
clutter_actor_box_get_size (allocation, &actor_width, &actor_height);
|
||||
|
||||
switch (bind->coordinate)
|
||||
{
|
||||
case CLUTTER_BIND_X:
|
||||
allocation->x1 = source_position.x + bind->offset;
|
||||
allocation->x2 = allocation->x1 + actor_width;
|
||||
break;
|
||||
|
||||
case CLUTTER_BIND_Y:
|
||||
allocation->y1 = source_position.y + bind->offset;
|
||||
allocation->y2 = allocation->y1 + actor_height;
|
||||
break;
|
||||
|
||||
case CLUTTER_BIND_POSITION:
|
||||
allocation->x1 = source_position.x + bind->offset;
|
||||
allocation->y1 = source_position.y + bind->offset;
|
||||
allocation->x2 = allocation->x1 + actor_width;
|
||||
allocation->y2 = allocation->y1 + actor_height;
|
||||
break;
|
||||
|
||||
case CLUTTER_BIND_WIDTH:
|
||||
allocation->x2 = allocation->x1 + source_width + bind->offset;
|
||||
break;
|
||||
|
||||
case CLUTTER_BIND_HEIGHT:
|
||||
allocation->y2 = allocation->y1 + source_height + bind->offset;
|
||||
break;
|
||||
|
||||
case CLUTTER_BIND_SIZE:
|
||||
allocation->x2 = allocation->x1 + source_width + bind->offset;
|
||||
allocation->y2 = allocation->y1 + source_height + bind->offset;
|
||||
break;
|
||||
|
||||
case CLUTTER_BIND_ALL:
|
||||
allocation->x1 = source_position.x + bind->offset;
|
||||
allocation->y1 = source_position.y + bind->offset;
|
||||
allocation->x2 = allocation->x1 + source_width + bind->offset;
|
||||
allocation->y2 = allocation->y1 + source_height + bind->offset;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
clutter_actor_box_clamp_to_pixel (allocation);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bind_constraint_set_actor (ClutterActorMeta *meta,
|
||||
ClutterActor *new_actor)
|
||||
{
|
||||
ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (meta);
|
||||
ClutterActorMetaClass *parent;
|
||||
|
||||
if (new_actor != NULL &&
|
||||
bind->source != NULL &&
|
||||
clutter_actor_contains (new_actor, bind->source))
|
||||
{
|
||||
g_warning (G_STRLOC ": The source actor '%s' is contained "
|
||||
"by the actor '%s' associated to the constraint "
|
||||
"'%s'",
|
||||
_clutter_actor_get_debug_name (bind->source),
|
||||
_clutter_actor_get_debug_name (new_actor),
|
||||
_clutter_actor_meta_get_debug_name (meta));
|
||||
return;
|
||||
}
|
||||
|
||||
/* store the pointer to the actor, for later use */
|
||||
bind->actor = new_actor;
|
||||
|
||||
parent = CLUTTER_ACTOR_META_CLASS (clutter_bind_constraint_parent_class);
|
||||
parent->set_actor (meta, new_actor);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bind_constraint_dispose (GObject *gobject)
|
||||
{
|
||||
ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (gobject);
|
||||
|
||||
if (bind->source != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (bind->source,
|
||||
G_CALLBACK (source_destroyed),
|
||||
bind);
|
||||
g_signal_handlers_disconnect_by_func (bind->source,
|
||||
G_CALLBACK (source_queue_relayout),
|
||||
bind);
|
||||
bind->source = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (clutter_bind_constraint_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bind_constraint_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SOURCE:
|
||||
clutter_bind_constraint_set_source (bind, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_COORDINATE:
|
||||
clutter_bind_constraint_set_coordinate (bind, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
case PROP_OFFSET:
|
||||
clutter_bind_constraint_set_offset (bind, g_value_get_float (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bind_constraint_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SOURCE:
|
||||
g_value_set_object (value, bind->source);
|
||||
break;
|
||||
|
||||
case PROP_COORDINATE:
|
||||
g_value_set_enum (value, bind->coordinate);
|
||||
break;
|
||||
|
||||
case PROP_OFFSET:
|
||||
g_value_set_float (value, bind->offset);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bind_constraint_class_init (ClutterBindConstraintClass *klass)
|
||||
{
|
||||
ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
|
||||
ClutterConstraintClass *constraint_class = CLUTTER_CONSTRAINT_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->set_property = clutter_bind_constraint_set_property;
|
||||
gobject_class->get_property = clutter_bind_constraint_get_property;
|
||||
gobject_class->dispose = clutter_bind_constraint_dispose;
|
||||
|
||||
meta_class->set_actor = clutter_bind_constraint_set_actor;
|
||||
|
||||
constraint_class->update_allocation = clutter_bind_constraint_update_allocation;
|
||||
constraint_class->update_preferred_size = clutter_bind_constraint_update_preferred_size;
|
||||
|
||||
/**
|
||||
* ClutterBindConstraint:source:
|
||||
*
|
||||
* The #ClutterActor used as the source for the binding.
|
||||
*
|
||||
* The #ClutterActor must not be contained inside the actor associated
|
||||
* to the constraint.
|
||||
*/
|
||||
obj_props[PROP_SOURCE] =
|
||||
g_param_spec_object ("source", NULL, NULL,
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT);
|
||||
|
||||
/**
|
||||
* ClutterBindConstraint:coordinate:
|
||||
*
|
||||
* The coordinate to be bound
|
||||
*/
|
||||
obj_props[PROP_COORDINATE] =
|
||||
g_param_spec_enum ("coordinate", NULL, NULL,
|
||||
CLUTTER_TYPE_BIND_COORDINATE,
|
||||
CLUTTER_BIND_X,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT);
|
||||
|
||||
/**
|
||||
* ClutterBindConstraint:offset:
|
||||
*
|
||||
* The offset, in pixels, to be applied to the binding
|
||||
*/
|
||||
obj_props[PROP_OFFSET] =
|
||||
g_param_spec_float ("offset", NULL, NULL,
|
||||
-G_MAXFLOAT, G_MAXFLOAT,
|
||||
0.0f,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT);
|
||||
|
||||
g_object_class_install_properties (gobject_class,
|
||||
PROP_LAST,
|
||||
obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bind_constraint_init (ClutterBindConstraint *self)
|
||||
{
|
||||
self->actor = NULL;
|
||||
self->source = NULL;
|
||||
self->coordinate = CLUTTER_BIND_X;
|
||||
self->offset = 0.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_bind_constraint_new:
|
||||
* @source: (allow-none): the #ClutterActor to use as the source of
|
||||
* the binding, or %NULL
|
||||
* @coordinate: the coordinate to bind
|
||||
* @offset: the offset to apply to the binding, in pixels
|
||||
*
|
||||
* Creates a new constraint, binding a #ClutterActor's position to
|
||||
* the given @coordinate of the position of @source
|
||||
*
|
||||
* Return value: the newly created #ClutterBindConstraint
|
||||
*/
|
||||
ClutterConstraint *
|
||||
clutter_bind_constraint_new (ClutterActor *source,
|
||||
ClutterBindCoordinate coordinate,
|
||||
gfloat offset)
|
||||
{
|
||||
g_return_val_if_fail (source == NULL || CLUTTER_IS_ACTOR (source), NULL);
|
||||
|
||||
return g_object_new (CLUTTER_TYPE_BIND_CONSTRAINT,
|
||||
"source", source,
|
||||
"coordinate", coordinate,
|
||||
"offset", offset,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_bind_constraint_set_source:
|
||||
* @constraint: a #ClutterBindConstraint
|
||||
* @source: (allow-none): a #ClutterActor, or %NULL to unset the source
|
||||
*
|
||||
* Sets the source #ClutterActor for the constraint
|
||||
*/
|
||||
void
|
||||
clutter_bind_constraint_set_source (ClutterBindConstraint *constraint,
|
||||
ClutterActor *source)
|
||||
{
|
||||
ClutterActor *old_source, *actor;
|
||||
ClutterActorMeta *meta;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint));
|
||||
g_return_if_fail (source == NULL || CLUTTER_IS_ACTOR (source));
|
||||
|
||||
if (constraint->source == source)
|
||||
return;
|
||||
|
||||
meta = CLUTTER_ACTOR_META (constraint);
|
||||
actor = clutter_actor_meta_get_actor (meta);
|
||||
if (source != NULL && actor != NULL)
|
||||
{
|
||||
if (clutter_actor_contains (actor, source))
|
||||
{
|
||||
g_warning (G_STRLOC ": The source actor '%s' is contained "
|
||||
"by the actor '%s' associated to the constraint "
|
||||
"'%s'",
|
||||
_clutter_actor_get_debug_name (source),
|
||||
_clutter_actor_get_debug_name (actor),
|
||||
_clutter_actor_meta_get_debug_name (meta));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
old_source = constraint->source;
|
||||
if (old_source != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (old_source,
|
||||
G_CALLBACK (source_destroyed),
|
||||
constraint);
|
||||
g_signal_handlers_disconnect_by_func (old_source,
|
||||
G_CALLBACK (source_queue_relayout),
|
||||
constraint);
|
||||
}
|
||||
|
||||
constraint->source = source;
|
||||
if (constraint->source != NULL)
|
||||
{
|
||||
g_signal_connect (constraint->source, "queue-relayout",
|
||||
G_CALLBACK (source_queue_relayout),
|
||||
constraint);
|
||||
g_signal_connect (constraint->source, "destroy",
|
||||
G_CALLBACK (source_destroyed),
|
||||
constraint);
|
||||
|
||||
if (constraint->actor != NULL)
|
||||
clutter_actor_queue_relayout (constraint->actor);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_SOURCE]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_bind_constraint_get_source:
|
||||
* @constraint: a #ClutterBindConstraint
|
||||
*
|
||||
* Retrieves the #ClutterActor set using [method@Clutter.BindConstraint.set_source]
|
||||
*
|
||||
* Return value: (transfer none): a pointer to the source actor
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_bind_constraint_get_source (ClutterBindConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint), NULL);
|
||||
|
||||
return constraint->source;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_bind_constraint_set_coordinate:
|
||||
* @constraint: a #ClutterBindConstraint
|
||||
* @coordinate: the coordinate to bind
|
||||
*
|
||||
* Sets the coordinate to bind in the constraint
|
||||
*/
|
||||
void
|
||||
clutter_bind_constraint_set_coordinate (ClutterBindConstraint *constraint,
|
||||
ClutterBindCoordinate coordinate)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint));
|
||||
|
||||
if (constraint->coordinate == coordinate)
|
||||
return;
|
||||
|
||||
constraint->coordinate = coordinate;
|
||||
|
||||
if (constraint->actor != NULL)
|
||||
clutter_actor_queue_relayout (constraint->actor);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_COORDINATE]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_bind_constraint_get_coordinate:
|
||||
* @constraint: a #ClutterBindConstraint
|
||||
*
|
||||
* Retrieves the bound coordinate of the constraint
|
||||
*
|
||||
* Return value: the bound coordinate
|
||||
*/
|
||||
ClutterBindCoordinate
|
||||
clutter_bind_constraint_get_coordinate (ClutterBindConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint),
|
||||
CLUTTER_BIND_X);
|
||||
|
||||
return constraint->coordinate;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_bind_constraint_set_offset:
|
||||
* @constraint: a #ClutterBindConstraint
|
||||
* @offset: the offset to apply, in pixels
|
||||
*
|
||||
* Sets the offset to be applied to the constraint
|
||||
*/
|
||||
void
|
||||
clutter_bind_constraint_set_offset (ClutterBindConstraint *constraint,
|
||||
gfloat offset)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint));
|
||||
|
||||
if (fabs (constraint->offset - offset) < 0.00001f)
|
||||
return;
|
||||
|
||||
constraint->offset = offset;
|
||||
|
||||
if (constraint->actor != NULL)
|
||||
clutter_actor_queue_relayout (constraint->actor);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_OFFSET]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_bind_constraint_get_offset:
|
||||
* @constraint: a #ClutterBindConstraint
|
||||
*
|
||||
* Retrieves the offset set using [method@Clutter.BindConstraint.set_offset]
|
||||
*
|
||||
* Return value: the offset, in pixels
|
||||
*/
|
||||
gfloat
|
||||
clutter_bind_constraint_get_offset (ClutterBindConstraint *bind)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_BIND_CONSTRAINT (bind), 0.0);
|
||||
|
||||
return bind->offset;
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-constraint.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_BIND_CONSTRAINT (clutter_bind_constraint_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_FINAL_TYPE (ClutterBindConstraint, clutter_bind_constraint,
|
||||
CLUTTER, BIND_CONSTRAINT, ClutterConstraint)
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterConstraint * clutter_bind_constraint_new (ClutterActor *source,
|
||||
ClutterBindCoordinate coordinate,
|
||||
gfloat offset);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_bind_constraint_set_source (ClutterBindConstraint *constraint,
|
||||
ClutterActor *source);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_bind_constraint_get_source (ClutterBindConstraint *constraint);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_bind_constraint_set_coordinate (ClutterBindConstraint *constraint,
|
||||
ClutterBindCoordinate coordinate);
|
||||
CLUTTER_EXPORT
|
||||
ClutterBindCoordinate clutter_bind_constraint_get_coordinate (ClutterBindConstraint *constraint);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_bind_constraint_set_offset (ClutterBindConstraint *constraint,
|
||||
gfloat offset);
|
||||
CLUTTER_EXPORT
|
||||
gfloat clutter_bind_constraint_get_offset (ClutterBindConstraint *constraint);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,898 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2008 Intel Corporation.
|
||||
*
|
||||
* Authored By: Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterBindingPool
|
||||
*
|
||||
* Pool for key bindings
|
||||
*
|
||||
* #ClutterBindingPool is a data structure holding a set of key bindings.
|
||||
* Each key binding associates a key symbol (eventually with modifiers)
|
||||
* to an action. A callback function is associated to each action.
|
||||
*
|
||||
* For a given key symbol and modifier mask combination there can be only one
|
||||
* action; for each action there can be only one callback. There can be
|
||||
* multiple actions with the same name, and the same callback can be used
|
||||
* to handle multiple key bindings.
|
||||
*
|
||||
* Actors requiring key bindings should create a new #ClutterBindingPool
|
||||
* inside their class initialization function and then install actions
|
||||
* like this:
|
||||
*
|
||||
* ```c
|
||||
* static void
|
||||
* foo_class_init (FooClass *klass)
|
||||
* {
|
||||
* ClutterBindingPool *binding_pool;
|
||||
*
|
||||
* binding_pool = clutter_binding_pool_get_for_class (klass);
|
||||
*
|
||||
* clutter_binding_pool_install_action (binding_pool, "move-up",
|
||||
* CLUTTER_Up, 0,
|
||||
* G_CALLBACK (foo_action_move_up),
|
||||
* NULL, NULL);
|
||||
* clutter_binding_pool_install_action (binding_pool, "move-up",
|
||||
* CLUTTER_KP_Up, 0,
|
||||
* G_CALLBACK (foo_action_move_up),
|
||||
* NULL, NULL);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* The callback has a signature of:
|
||||
*
|
||||
* ```c
|
||||
* gboolean (* callback) (GObject *instance,
|
||||
* const gchar *action_name,
|
||||
* guint key_val,
|
||||
* ClutterModifierType modifiers,
|
||||
* gpointer user_data);
|
||||
* ```
|
||||
*
|
||||
* The actor should then override the [signal@Actor::key-press-event] and
|
||||
* use [method@BindingPool.activate] to match a [struct@Event] key event
|
||||
* structure to one of the actions:
|
||||
*
|
||||
* ```c
|
||||
* ClutterBindingPool *pool;
|
||||
*
|
||||
* // retrieve the binding pool for the type of the actor
|
||||
* pool = clutter_binding_pool_find (G_OBJECT_TYPE_NAME (actor));
|
||||
*
|
||||
* // activate any callback matching the key symbol and modifiers
|
||||
* // mask of the key event. the returned value can be directly
|
||||
* // used to signal that the actor has handled the event.
|
||||
* return clutter_binding_pool_activate (pool,
|
||||
* key_event->keyval,
|
||||
* key_event->modifier_state,
|
||||
* G_OBJECT (actor));
|
||||
* ```
|
||||
*
|
||||
* The [method@BindingPool.activate] function will return %FALSE if
|
||||
* no action for the given key binding was found, if the action was
|
||||
* blocked (using [method@BindingPool.block_action]) or if the
|
||||
* key binding handler returned %FALSE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-binding-pool.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-enum-types.h"
|
||||
#include "clutter/clutter-marshal.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
#define BINDING_MOD_MASK ((CLUTTER_SHIFT_MASK | \
|
||||
CLUTTER_CONTROL_MASK | \
|
||||
CLUTTER_MOD1_MASK | \
|
||||
CLUTTER_SUPER_MASK | \
|
||||
CLUTTER_HYPER_MASK | \
|
||||
CLUTTER_META_MASK) | CLUTTER_RELEASE_MASK)
|
||||
|
||||
typedef struct _ClutterBindingEntry ClutterBindingEntry;
|
||||
|
||||
static GSList *clutter_binding_pools = NULL;
|
||||
static GQuark key_class_bindings = 0;
|
||||
|
||||
struct _ClutterBindingPool
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
gchar *name; /* interned string, do not free */
|
||||
|
||||
GSList *entries;
|
||||
GHashTable *entries_hash;
|
||||
};
|
||||
|
||||
struct _ClutterBindingEntry
|
||||
{
|
||||
gchar *name; /* interned string, do not free */
|
||||
|
||||
guint key_val;
|
||||
ClutterModifierType modifiers;
|
||||
|
||||
GClosure *closure;
|
||||
|
||||
guint is_blocked : 1;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_NAME,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
G_DEFINE_FINAL_TYPE (ClutterBindingPool, clutter_binding_pool, G_TYPE_OBJECT);
|
||||
|
||||
static guint
|
||||
binding_entry_hash (gconstpointer v)
|
||||
{
|
||||
const ClutterBindingEntry *e = v;
|
||||
guint h;
|
||||
|
||||
h = e->key_val;
|
||||
h ^= e->modifiers;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
static gint
|
||||
binding_entry_compare (gconstpointer v1,
|
||||
gconstpointer v2)
|
||||
{
|
||||
const ClutterBindingEntry *e1 = v1;
|
||||
const ClutterBindingEntry *e2 = v2;
|
||||
|
||||
return (e1->key_val == e2->key_val && e1->modifiers == e2->modifiers);
|
||||
}
|
||||
|
||||
static ClutterBindingEntry *
|
||||
binding_entry_new (const gchar *name,
|
||||
guint key_val,
|
||||
ClutterModifierType modifiers)
|
||||
{
|
||||
ClutterBindingEntry *entry;
|
||||
|
||||
modifiers = modifiers & BINDING_MOD_MASK;
|
||||
|
||||
entry = g_new0 (ClutterBindingEntry, 1);
|
||||
entry->key_val = key_val;
|
||||
entry->modifiers = modifiers;
|
||||
entry->name = (gchar *) g_intern_string (name);
|
||||
entry->closure = NULL;
|
||||
entry->is_blocked = FALSE;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
static ClutterBindingEntry *
|
||||
binding_pool_lookup_entry (ClutterBindingPool *pool,
|
||||
guint key_val,
|
||||
ClutterModifierType modifiers)
|
||||
{
|
||||
ClutterBindingEntry lookup_entry = { 0, };
|
||||
|
||||
lookup_entry.key_val = key_val;
|
||||
lookup_entry.modifiers = modifiers;
|
||||
|
||||
return g_hash_table_lookup (pool->entries_hash, &lookup_entry);
|
||||
}
|
||||
|
||||
static void
|
||||
binding_entry_free (gpointer data)
|
||||
{
|
||||
if (G_LIKELY (data))
|
||||
{
|
||||
ClutterBindingEntry *entry = data;
|
||||
|
||||
g_closure_unref (entry->closure);
|
||||
|
||||
g_free (entry);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_binding_pool_finalize (GObject *gobject)
|
||||
{
|
||||
ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject);
|
||||
|
||||
/* remove from the pools */
|
||||
clutter_binding_pools = g_slist_remove (clutter_binding_pools, pool);
|
||||
|
||||
g_hash_table_destroy (pool->entries_hash);
|
||||
|
||||
g_slist_free_full (pool->entries, (GDestroyNotify) binding_entry_free);
|
||||
|
||||
G_OBJECT_CLASS (clutter_binding_pool_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_binding_pool_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
pool->name = (gchar *) g_intern_string (g_value_get_string (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_binding_pool_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, pool->name);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_binding_pool_constructed (GObject *gobject)
|
||||
{
|
||||
ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject);
|
||||
|
||||
/* bad monkey! bad, bad monkey! */
|
||||
if (G_UNLIKELY (pool->name == NULL))
|
||||
g_critical ("No name set for ClutterBindingPool %p", pool);
|
||||
|
||||
if (G_OBJECT_CLASS (clutter_binding_pool_parent_class)->constructed)
|
||||
G_OBJECT_CLASS (clutter_binding_pool_parent_class)->constructed (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_binding_pool_class_init (ClutterBindingPoolClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->constructed = clutter_binding_pool_constructed;
|
||||
gobject_class->set_property = clutter_binding_pool_set_property;
|
||||
gobject_class->get_property = clutter_binding_pool_get_property;
|
||||
gobject_class->finalize = clutter_binding_pool_finalize;
|
||||
|
||||
/**
|
||||
* ClutterBindingPool:name:
|
||||
*
|
||||
* The unique name of the #ClutterBindingPool.
|
||||
*/
|
||||
obj_props[PROP_NAME] =
|
||||
g_param_spec_string ("name", NULL, NULL,
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (gobject_class,
|
||||
PROP_LAST,
|
||||
obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_binding_pool_init (ClutterBindingPool *pool)
|
||||
{
|
||||
pool->name = NULL;
|
||||
pool->entries = NULL;
|
||||
pool->entries_hash = g_hash_table_new (binding_entry_hash,
|
||||
binding_entry_compare);
|
||||
|
||||
clutter_binding_pools = g_slist_prepend (clutter_binding_pools, pool);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_binding_pool_new:
|
||||
* @name: the name of the binding pool
|
||||
*
|
||||
* Creates a new #ClutterBindingPool that can be used to store
|
||||
* key bindings for an actor. The @name must be a unique identifier
|
||||
* for the binding pool, so that [func@Clutter.BindingPool.find] will
|
||||
* be able to return the correct binding pool.
|
||||
*
|
||||
* Return value: the newly created binding pool with the given
|
||||
* name. Use g_object_unref() when done.
|
||||
*/
|
||||
ClutterBindingPool *
|
||||
clutter_binding_pool_new (const gchar *name)
|
||||
{
|
||||
ClutterBindingPool *pool;
|
||||
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
pool = clutter_binding_pool_find (name);
|
||||
if (G_UNLIKELY (pool))
|
||||
{
|
||||
g_warning ("A binding pool named '%s' is already present "
|
||||
"in the binding pools list",
|
||||
pool->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_object_new (CLUTTER_TYPE_BINDING_POOL, "name", name, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_binding_pool_get_for_class:
|
||||
* @klass: a #GObjectClass pointer
|
||||
*
|
||||
* Retrieves the #ClutterBindingPool for the given #GObject class
|
||||
* and, eventually, creates it. This function is a wrapper around
|
||||
* [ctor@Clutter.BindingPool.new] and uses the class type name as the
|
||||
* unique name for the binding pool.
|
||||
*
|
||||
* Calling this function multiple times will return the same
|
||||
* #ClutterBindingPool.
|
||||
*
|
||||
* A binding pool for a class can also be retrieved using
|
||||
* [func@Clutter.BindingPool.find] with the class type name:
|
||||
*
|
||||
* ```
|
||||
* pool = clutter_binding_pool_find (G_OBJECT_TYPE_NAME (instance));
|
||||
* ```
|
||||
*
|
||||
* Return value: (transfer none): the binding pool for the given class.
|
||||
* The returned #ClutterBindingPool is owned by Clutter and should not
|
||||
* be freed directly
|
||||
*/
|
||||
ClutterBindingPool *
|
||||
clutter_binding_pool_get_for_class (gpointer klass)
|
||||
{
|
||||
ClutterBindingPool *pool;
|
||||
|
||||
g_return_val_if_fail (G_IS_OBJECT_CLASS (klass), NULL);
|
||||
|
||||
if (G_UNLIKELY (key_class_bindings == 0))
|
||||
key_class_bindings = g_quark_from_static_string ("clutter-bindings-set");
|
||||
|
||||
pool = g_dataset_id_get_data (klass, key_class_bindings);
|
||||
if (pool)
|
||||
return pool;
|
||||
|
||||
pool = clutter_binding_pool_new (G_OBJECT_CLASS_NAME (klass));
|
||||
g_dataset_id_set_data_full (klass, key_class_bindings,
|
||||
pool,
|
||||
g_object_unref);
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_binding_pool_find:
|
||||
* @name: the name of the binding pool to find
|
||||
*
|
||||
* Finds the #ClutterBindingPool with @name.
|
||||
*
|
||||
* Return value: (transfer none): a pointer to the #ClutterBindingPool, or %NULL
|
||||
*/
|
||||
ClutterBindingPool *
|
||||
clutter_binding_pool_find (const gchar *name)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
for (l = clutter_binding_pools; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterBindingPool *pool = l->data;
|
||||
|
||||
if (g_str_equal (pool->name, (gpointer) name))
|
||||
return pool;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_binding_pool_install_action:
|
||||
* @pool: a #ClutterBindingPool
|
||||
* @action_name: the name of the action
|
||||
* @key_val: key symbol
|
||||
* @modifiers: bitmask of modifiers
|
||||
* @callback: function to be called
|
||||
* when the action is activated
|
||||
* @data: data to be passed to @callback
|
||||
* @notify: function to be called when the action is removed
|
||||
* from the pool
|
||||
*
|
||||
* Installs a new action inside a #ClutterBindingPool. The action
|
||||
* is bound to @key_val and @modifiers.
|
||||
*
|
||||
* The same action name can be used for multiple @key_val, @modifiers
|
||||
* pairs.
|
||||
*
|
||||
* When an action has been activated using [method@Clutter.BindingPool.activate]
|
||||
* the passed @callback will be invoked (with @data).
|
||||
*
|
||||
* Actions can be blocked with [method@Clutter.BindingPool.block_action]
|
||||
* and then unblocked using [method@Clutter.BindingPool.unblock_action].
|
||||
*/
|
||||
void
|
||||
clutter_binding_pool_install_action (ClutterBindingPool *pool,
|
||||
const gchar *action_name,
|
||||
guint key_val,
|
||||
ClutterModifierType modifiers,
|
||||
GCallback callback,
|
||||
gpointer data,
|
||||
GDestroyNotify notify)
|
||||
{
|
||||
ClutterBindingEntry *entry;
|
||||
GClosure *closure;
|
||||
|
||||
g_return_if_fail (pool != NULL);
|
||||
g_return_if_fail (action_name != NULL);
|
||||
g_return_if_fail (key_val != 0);
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
entry = binding_pool_lookup_entry (pool, key_val, modifiers);
|
||||
if (G_UNLIKELY (entry))
|
||||
{
|
||||
g_warning ("There already is an action '%s' for the given "
|
||||
"key symbol of %d (modifiers: %d) installed inside "
|
||||
"the binding pool.",
|
||||
entry->name,
|
||||
entry->key_val, entry->modifiers);
|
||||
return;
|
||||
}
|
||||
else
|
||||
entry = binding_entry_new (action_name, key_val, modifiers);
|
||||
|
||||
closure = g_cclosure_new (callback, data, (GClosureNotify) notify);
|
||||
entry->closure = g_closure_ref (closure);
|
||||
g_closure_sink (closure);
|
||||
|
||||
if (G_CLOSURE_NEEDS_MARSHAL (closure))
|
||||
{
|
||||
GClosureMarshal marshal;
|
||||
|
||||
marshal = _clutter_marshal_BOOLEAN__STRING_UINT_FLAGS;
|
||||
g_closure_set_marshal (closure, marshal);
|
||||
}
|
||||
|
||||
pool->entries = g_slist_prepend (pool->entries, entry);
|
||||
g_hash_table_insert (pool->entries_hash, entry, entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_binding_pool_install_closure:
|
||||
* @pool: a #ClutterBindingPool
|
||||
* @action_name: the name of the action
|
||||
* @key_val: key symbol
|
||||
* @modifiers: bitmask of modifiers
|
||||
* @closure: a #GClosure
|
||||
*
|
||||
* A #GClosure variant of [method@Clutter.BindingPool.install_action].
|
||||
*
|
||||
* Installs a new action inside a #ClutterBindingPool. The action
|
||||
* is bound to @key_val and @modifiers.
|
||||
*
|
||||
* The same action name can be used for multiple @key_val, @modifiers
|
||||
* pairs.
|
||||
*
|
||||
* When an action has been activated using [method@Clutter.BindingPool.activate]
|
||||
* the passed @closure will be invoked.
|
||||
*
|
||||
* Actions can be blocked with [method@Clutter.BindingPool.block_action]
|
||||
* and then unblocked using [method@Clutter.BindingPool.unblock_action].
|
||||
*/
|
||||
void
|
||||
clutter_binding_pool_install_closure (ClutterBindingPool *pool,
|
||||
const gchar *action_name,
|
||||
guint key_val,
|
||||
ClutterModifierType modifiers,
|
||||
GClosure *closure)
|
||||
{
|
||||
ClutterBindingEntry *entry;
|
||||
|
||||
g_return_if_fail (pool != NULL);
|
||||
g_return_if_fail (action_name != NULL);
|
||||
g_return_if_fail (key_val != 0);
|
||||
g_return_if_fail (closure != NULL);
|
||||
|
||||
entry = binding_pool_lookup_entry (pool, key_val, modifiers);
|
||||
if (G_UNLIKELY (entry))
|
||||
{
|
||||
g_warning ("There already is an action '%s' for the given "
|
||||
"key symbol of %d (modifiers: %d) installed inside "
|
||||
"the binding pool.",
|
||||
entry->name,
|
||||
entry->key_val, entry->modifiers);
|
||||
return;
|
||||
}
|
||||
else
|
||||
entry = binding_entry_new (action_name, key_val, modifiers);
|
||||
|
||||
entry->closure = g_closure_ref (closure);
|
||||
g_closure_sink (closure);
|
||||
|
||||
if (G_CLOSURE_NEEDS_MARSHAL (closure))
|
||||
{
|
||||
GClosureMarshal marshal;
|
||||
|
||||
marshal = _clutter_marshal_BOOLEAN__STRING_UINT_FLAGS;
|
||||
g_closure_set_marshal (closure, marshal);
|
||||
}
|
||||
|
||||
pool->entries = g_slist_prepend (pool->entries, entry);
|
||||
g_hash_table_insert (pool->entries_hash, entry, entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_binding_pool_override_action:
|
||||
* @pool: a #ClutterBindingPool
|
||||
* @key_val: key symbol
|
||||
* @modifiers: bitmask of modifiers
|
||||
* @callback: function to be called when the action is activated
|
||||
* @data: data to be passed to @callback
|
||||
* @notify: function to be called when the action is removed
|
||||
* from the pool
|
||||
*
|
||||
* Allows overriding the action for @key_val and @modifiers inside a
|
||||
* #ClutterBindingPool. See [method@Clutter.BindingPool.install_action].
|
||||
*
|
||||
* When an action has been activated using [method@Clutter.BindingPool.activate]
|
||||
* the passed @callback will be invoked (with @data).
|
||||
*
|
||||
* Actions can be blocked with [method@Clutter.BindingPool.block_action]
|
||||
* and then unblocked using [method@Clutter.BindingPool.unblock_action].
|
||||
*/
|
||||
void
|
||||
clutter_binding_pool_override_action (ClutterBindingPool *pool,
|
||||
guint key_val,
|
||||
ClutterModifierType modifiers,
|
||||
GCallback callback,
|
||||
gpointer data,
|
||||
GDestroyNotify notify)
|
||||
{
|
||||
ClutterBindingEntry *entry;
|
||||
GClosure *closure;
|
||||
|
||||
g_return_if_fail (pool != NULL);
|
||||
g_return_if_fail (key_val != 0);
|
||||
g_return_if_fail (callback != NULL);
|
||||
|
||||
entry = binding_pool_lookup_entry (pool, key_val, modifiers);
|
||||
if (G_UNLIKELY (entry == NULL))
|
||||
{
|
||||
g_warning ("There is no action for the given key symbol "
|
||||
"of %d (modifiers: %d) installed inside the "
|
||||
"binding pool.",
|
||||
key_val, modifiers);
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry->closure)
|
||||
{
|
||||
g_closure_unref (entry->closure);
|
||||
entry->closure = NULL;
|
||||
}
|
||||
|
||||
closure = g_cclosure_new (callback, data, (GClosureNotify) notify);
|
||||
entry->closure = g_closure_ref (closure);
|
||||
g_closure_sink (closure);
|
||||
|
||||
if (G_CLOSURE_NEEDS_MARSHAL (closure))
|
||||
{
|
||||
GClosureMarshal marshal;
|
||||
|
||||
marshal = _clutter_marshal_BOOLEAN__STRING_UINT_FLAGS;
|
||||
g_closure_set_marshal (closure, marshal);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_binding_pool_override_closure:
|
||||
* @pool: a #ClutterBindingPool
|
||||
* @key_val: key symbol
|
||||
* @modifiers: bitmask of modifiers
|
||||
* @closure: a #GClosure
|
||||
*
|
||||
* A #GClosure variant of [method@Clutter.BindingPool.override_action].
|
||||
*
|
||||
* Allows overriding the action for @key_val and @modifiers inside a
|
||||
* #ClutterBindingPool. See [method@Clutter.BindingPool.install_closure].
|
||||
*
|
||||
* When an action has been activated using [method@Clutter.BindingPool.activate]
|
||||
* the passed @callback will be invoked (with @data).
|
||||
*
|
||||
* Actions can be blocked with [method@Clutter.BindingPool.block_action]
|
||||
* and then unblocked using [method@Clutter.BindingPool.unblock_action].
|
||||
*/
|
||||
void
|
||||
clutter_binding_pool_override_closure (ClutterBindingPool *pool,
|
||||
guint key_val,
|
||||
ClutterModifierType modifiers,
|
||||
GClosure *closure)
|
||||
{
|
||||
ClutterBindingEntry *entry;
|
||||
|
||||
g_return_if_fail (pool != NULL);
|
||||
g_return_if_fail (key_val != 0);
|
||||
g_return_if_fail (closure != NULL);
|
||||
|
||||
entry = binding_pool_lookup_entry (pool, key_val, modifiers);
|
||||
if (G_UNLIKELY (entry == NULL))
|
||||
{
|
||||
g_warning ("There is no action for the given key symbol "
|
||||
"of %d (modifiers: %d) installed inside the "
|
||||
"binding pool.",
|
||||
key_val, modifiers);
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry->closure)
|
||||
{
|
||||
g_closure_unref (entry->closure);
|
||||
entry->closure = NULL;
|
||||
}
|
||||
|
||||
entry->closure = g_closure_ref (closure);
|
||||
g_closure_sink (closure);
|
||||
|
||||
if (G_CLOSURE_NEEDS_MARSHAL (closure))
|
||||
{
|
||||
GClosureMarshal marshal;
|
||||
|
||||
marshal = _clutter_marshal_BOOLEAN__STRING_UINT_FLAGS;
|
||||
g_closure_set_marshal (closure, marshal);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_binding_pool_find_action:
|
||||
* @pool: a #ClutterBindingPool
|
||||
* @key_val: a key symbol
|
||||
* @modifiers: a bitmask for the modifiers
|
||||
*
|
||||
* Retrieves the name of the action matching the given key symbol
|
||||
* and modifiers bitmask.
|
||||
*
|
||||
* Return value: the name of the action, if found, or %NULL. The
|
||||
* returned string is owned by the binding pool and should never
|
||||
* be modified or freed
|
||||
*/
|
||||
const gchar *
|
||||
clutter_binding_pool_find_action (ClutterBindingPool *pool,
|
||||
guint key_val,
|
||||
ClutterModifierType modifiers)
|
||||
{
|
||||
ClutterBindingEntry *entry;
|
||||
|
||||
g_return_val_if_fail (pool != NULL, NULL);
|
||||
g_return_val_if_fail (key_val != 0, NULL);
|
||||
|
||||
entry = binding_pool_lookup_entry (pool, key_val, modifiers);
|
||||
if (!entry)
|
||||
return NULL;
|
||||
|
||||
return entry->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_binding_pool_remove_action:
|
||||
* @pool: a #ClutterBindingPool
|
||||
* @key_val: a key symbol
|
||||
* @modifiers: a bitmask for the modifiers
|
||||
*
|
||||
* Removes the action matching the given @key_val, @modifiers pair,
|
||||
* if any exists.
|
||||
*/
|
||||
void
|
||||
clutter_binding_pool_remove_action (ClutterBindingPool *pool,
|
||||
guint key_val,
|
||||
ClutterModifierType modifiers)
|
||||
{
|
||||
ClutterBindingEntry remove_entry = { 0, };
|
||||
GSList *l;
|
||||
|
||||
g_return_if_fail (pool != NULL);
|
||||
g_return_if_fail (key_val != 0);
|
||||
|
||||
modifiers = modifiers & BINDING_MOD_MASK;
|
||||
|
||||
remove_entry.key_val = key_val;
|
||||
remove_entry.modifiers = modifiers;
|
||||
|
||||
for (l = pool->entries; l != NULL; l = l->data)
|
||||
{
|
||||
ClutterBindingEntry *e = l->data;
|
||||
|
||||
if (e->key_val == remove_entry.key_val &&
|
||||
e->modifiers == remove_entry.modifiers)
|
||||
{
|
||||
pool->entries = g_slist_remove_link (pool->entries, l);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_remove (pool->entries_hash, &remove_entry);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_binding_entry_invoke (ClutterBindingEntry *entry,
|
||||
GObject *gobject)
|
||||
{
|
||||
GValue params[4] = {
|
||||
G_VALUE_INIT,
|
||||
G_VALUE_INIT,
|
||||
G_VALUE_INIT,
|
||||
G_VALUE_INIT
|
||||
};
|
||||
GValue result = G_VALUE_INIT;
|
||||
gboolean retval = TRUE;
|
||||
|
||||
g_value_init (¶ms[0], G_TYPE_OBJECT);
|
||||
g_value_set_object (¶ms[0], gobject);
|
||||
|
||||
g_value_init (¶ms[1], G_TYPE_STRING);
|
||||
g_value_set_static_string (¶ms[1], entry->name);
|
||||
|
||||
g_value_init (¶ms[2], G_TYPE_UINT);
|
||||
g_value_set_uint (¶ms[2], entry->key_val);
|
||||
|
||||
g_value_init (¶ms[3], CLUTTER_TYPE_MODIFIER_TYPE);
|
||||
g_value_set_flags (¶ms[3], entry->modifiers);
|
||||
|
||||
g_value_init (&result, G_TYPE_BOOLEAN);
|
||||
|
||||
g_closure_invoke (entry->closure, &result, 4, params, NULL);
|
||||
|
||||
retval = g_value_get_boolean (&result);
|
||||
|
||||
g_value_unset (&result);
|
||||
|
||||
g_value_unset (¶ms[0]);
|
||||
g_value_unset (¶ms[1]);
|
||||
g_value_unset (¶ms[2]);
|
||||
g_value_unset (¶ms[3]);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_binding_pool_activate:
|
||||
* @pool: a #ClutterBindingPool
|
||||
* @key_val: the key symbol
|
||||
* @modifiers: bitmask for the modifiers
|
||||
* @gobject: a #GObject
|
||||
*
|
||||
* Activates the callback associated to the action that is
|
||||
* bound to the @key_val and @modifiers pair.
|
||||
*
|
||||
* The callback has the following signature:
|
||||
*
|
||||
* ```
|
||||
* void (* callback) (GObject *gobject,
|
||||
* const gchar *action_name,
|
||||
* guint key_val,
|
||||
* ClutterModifierType modifiers,
|
||||
* gpointer user_data);
|
||||
* ```
|
||||
*
|
||||
* Where the #GObject instance is @gobject and the user data
|
||||
* is the one passed when installing the action with
|
||||
* [method@Clutter.BindingPool.install_action].
|
||||
*
|
||||
* If the action bound to the @key_val, @modifiers pair has been
|
||||
* blocked using [method@Clutter.BindingPool.block_action], the callback
|
||||
* will not be invoked, and this function will return %FALSE.
|
||||
*
|
||||
* Return value: %TRUE if an action was found and was activated
|
||||
*/
|
||||
gboolean
|
||||
clutter_binding_pool_activate (ClutterBindingPool *pool,
|
||||
guint key_val,
|
||||
ClutterModifierType modifiers,
|
||||
GObject *gobject)
|
||||
{
|
||||
ClutterBindingEntry *entry = NULL;
|
||||
|
||||
g_return_val_if_fail (pool != NULL, FALSE);
|
||||
g_return_val_if_fail (key_val != 0, FALSE);
|
||||
g_return_val_if_fail (G_IS_OBJECT (gobject), FALSE);
|
||||
|
||||
modifiers = (modifiers & BINDING_MOD_MASK);
|
||||
|
||||
entry = binding_pool_lookup_entry (pool, key_val, modifiers);
|
||||
if (!entry)
|
||||
return FALSE;
|
||||
|
||||
if (!entry->is_blocked)
|
||||
return clutter_binding_entry_invoke (entry, gobject);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_binding_pool_block_action:
|
||||
* @pool: a #ClutterBindingPool
|
||||
* @action_name: an action name
|
||||
*
|
||||
* Blocks all the actions with name @action_name inside @pool.
|
||||
*/
|
||||
void
|
||||
clutter_binding_pool_block_action (ClutterBindingPool *pool,
|
||||
const gchar *action_name)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
g_return_if_fail (pool != NULL);
|
||||
g_return_if_fail (action_name != NULL);
|
||||
|
||||
for (l = pool->entries; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterBindingEntry *entry = l->data;
|
||||
|
||||
if (g_str_equal (entry->name, (gpointer) action_name))
|
||||
entry->is_blocked = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_binding_pool_unblock_action:
|
||||
* @pool: a #ClutterBindingPool
|
||||
* @action_name: an action name
|
||||
*
|
||||
* Unblockes all the actions with name @action_name inside @pool.
|
||||
*
|
||||
* Unblocking an action does not cause the callback bound to it to
|
||||
* be invoked in case [method@Clutter.BindingPool.activate] was called on
|
||||
* an action previously blocked with [method@Clutter.BindingPool.block_action].
|
||||
*/
|
||||
void
|
||||
clutter_binding_pool_unblock_action (ClutterBindingPool *pool,
|
||||
const gchar *action_name)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
g_return_if_fail (pool != NULL);
|
||||
g_return_if_fail (action_name != NULL);
|
||||
|
||||
for (l = pool->entries; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterBindingEntry *entry = l->data;
|
||||
|
||||
if (g_str_equal (entry->name, (gpointer) action_name))
|
||||
entry->is_blocked = FALSE;
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2008 Intel Corporation.
|
||||
*
|
||||
* Authored By: Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "clutter/clutter-event.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_BINDING_POOL (clutter_binding_pool_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_FINAL_TYPE (ClutterBindingPool,
|
||||
clutter_binding_pool,
|
||||
CLUTTER,
|
||||
BINDING_POOL,
|
||||
GObject)
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterBindingPool * clutter_binding_pool_new (const gchar *name);
|
||||
CLUTTER_EXPORT
|
||||
ClutterBindingPool * clutter_binding_pool_get_for_class (gpointer klass);
|
||||
CLUTTER_EXPORT
|
||||
ClutterBindingPool * clutter_binding_pool_find (const gchar *name);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_binding_pool_install_action (ClutterBindingPool *pool,
|
||||
const gchar *action_name,
|
||||
guint key_val,
|
||||
ClutterModifierType modifiers,
|
||||
GCallback callback,
|
||||
gpointer data,
|
||||
GDestroyNotify notify);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_binding_pool_install_closure (ClutterBindingPool *pool,
|
||||
const gchar *action_name,
|
||||
guint key_val,
|
||||
ClutterModifierType modifiers,
|
||||
GClosure *closure);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_binding_pool_override_action (ClutterBindingPool *pool,
|
||||
guint key_val,
|
||||
ClutterModifierType modifiers,
|
||||
GCallback callback,
|
||||
gpointer data,
|
||||
GDestroyNotify notify);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_binding_pool_override_closure (ClutterBindingPool *pool,
|
||||
guint key_val,
|
||||
ClutterModifierType modifiers,
|
||||
GClosure *closure);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
const gchar * clutter_binding_pool_find_action (ClutterBindingPool *pool,
|
||||
guint key_val,
|
||||
ClutterModifierType modifiers);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_binding_pool_remove_action (ClutterBindingPool *pool,
|
||||
guint key_val,
|
||||
ClutterModifierType modifiers);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_binding_pool_activate (ClutterBindingPool *pool,
|
||||
guint key_val,
|
||||
ClutterModifierType modifiers,
|
||||
GObject *gobject);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_binding_pool_block_action (ClutterBindingPool *pool,
|
||||
const gchar *action_name);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_binding_pool_unblock_action (ClutterBindingPool *pool,
|
||||
const gchar *action_name);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,206 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterBlurEffect:
|
||||
*
|
||||
* A blur effect
|
||||
*
|
||||
* #ClutterBlurEffect is a sub-class of #ClutterEffect that allows blurring a
|
||||
* actor and its contents.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-blur-effect.h"
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
#define BLUR_PADDING 2
|
||||
|
||||
/* FIXME - lame shader; we should really have a decoupled
|
||||
* horizontal/vertical two pass shader for the gaussian blur
|
||||
*/
|
||||
static const gchar *box_blur_glsl_declarations =
|
||||
"uniform vec2 pixel_step;\n";
|
||||
#define SAMPLE(offx, offy) \
|
||||
"cogl_texel += texture2D (cogl_sampler, cogl_tex_coord.st + pixel_step * " \
|
||||
"vec2 (" G_STRINGIFY (offx) ", " G_STRINGIFY (offy) "));\n"
|
||||
static const gchar *box_blur_glsl_shader =
|
||||
" cogl_texel = texture2D (cogl_sampler, cogl_tex_coord.st);\n"
|
||||
SAMPLE (-1.0, -1.0)
|
||||
SAMPLE ( 0.0, -1.0)
|
||||
SAMPLE (+1.0, -1.0)
|
||||
SAMPLE (-1.0, 0.0)
|
||||
SAMPLE (+1.0, 0.0)
|
||||
SAMPLE (-1.0, +1.0)
|
||||
SAMPLE ( 0.0, +1.0)
|
||||
SAMPLE (+1.0, +1.0)
|
||||
" cogl_texel /= 9.0;\n";
|
||||
#undef SAMPLE
|
||||
|
||||
typedef struct _ClutterBlurEffectPrivate
|
||||
{
|
||||
/* a back pointer to our actor, so that we can query it */
|
||||
ClutterActor *actor;
|
||||
|
||||
gint pixel_step_uniform;
|
||||
|
||||
CoglPipeline *pipeline;
|
||||
} ClutterBlurEffectPrivate;
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterBlurEffect,
|
||||
clutter_blur_effect,
|
||||
CLUTTER_TYPE_OFFSCREEN_EFFECT);
|
||||
|
||||
static CoglPipeline *
|
||||
clutter_blur_effect_create_pipeline (ClutterOffscreenEffect *effect,
|
||||
CoglTexture *texture)
|
||||
{
|
||||
ClutterBlurEffect *blur_effect = CLUTTER_BLUR_EFFECT (effect);
|
||||
ClutterBlurEffectPrivate *priv =
|
||||
clutter_blur_effect_get_instance_private (blur_effect);
|
||||
|
||||
if (priv->pixel_step_uniform > -1)
|
||||
{
|
||||
float pixel_step[2];
|
||||
int tex_width, tex_height;
|
||||
|
||||
tex_width = cogl_texture_get_width (texture);
|
||||
tex_height = cogl_texture_get_height (texture);
|
||||
|
||||
pixel_step[0] = 1.0f / tex_width;
|
||||
pixel_step[1] = 1.0f / tex_height;
|
||||
|
||||
cogl_pipeline_set_uniform_float (priv->pipeline,
|
||||
priv->pixel_step_uniform,
|
||||
2, /* n_components */
|
||||
1, /* count */
|
||||
pixel_step);
|
||||
}
|
||||
|
||||
cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture);
|
||||
|
||||
return g_object_ref (priv->pipeline);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_blur_effect_modify_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
gfloat cur_width, cur_height;
|
||||
graphene_point3d_t origin;
|
||||
|
||||
clutter_paint_volume_get_origin (volume, &origin);
|
||||
cur_width = clutter_paint_volume_get_width (volume);
|
||||
cur_height = clutter_paint_volume_get_height (volume);
|
||||
|
||||
origin.x -= BLUR_PADDING;
|
||||
origin.y -= BLUR_PADDING;
|
||||
cur_width += 2 * BLUR_PADDING;
|
||||
cur_height += 2 * BLUR_PADDING;
|
||||
clutter_paint_volume_set_origin (volume, &origin);
|
||||
clutter_paint_volume_set_width (volume, cur_width);
|
||||
clutter_paint_volume_set_height (volume, cur_height);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_blur_effect_dispose (GObject *gobject)
|
||||
{
|
||||
ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (gobject);
|
||||
ClutterBlurEffectPrivate *priv =
|
||||
clutter_blur_effect_get_instance_private (self);
|
||||
|
||||
g_clear_object (&priv->pipeline);
|
||||
|
||||
G_OBJECT_CLASS (clutter_blur_effect_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_blur_effect_class_init (ClutterBlurEffectClass *klass)
|
||||
{
|
||||
ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterOffscreenEffectClass *offscreen_class;
|
||||
|
||||
gobject_class->dispose = clutter_blur_effect_dispose;
|
||||
|
||||
effect_class->modify_paint_volume = clutter_blur_effect_modify_paint_volume;
|
||||
|
||||
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
||||
offscreen_class->create_pipeline = clutter_blur_effect_create_pipeline;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_blur_effect_init (ClutterBlurEffect *self)
|
||||
{
|
||||
ClutterBlurEffectClass *klass = CLUTTER_BLUR_EFFECT_GET_CLASS (self);
|
||||
ClutterBlurEffectPrivate *priv =
|
||||
clutter_blur_effect_get_instance_private (self);
|
||||
|
||||
if (G_UNLIKELY (klass->base_pipeline == NULL))
|
||||
{
|
||||
CoglSnippet *snippet;
|
||||
ClutterContext *context = _clutter_context_get_default ();
|
||||
ClutterBackend *backend = clutter_context_get_backend (context);
|
||||
CoglContext *cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
|
||||
klass->base_pipeline = cogl_pipeline_new (cogl_context);
|
||||
cogl_pipeline_set_static_name (klass->base_pipeline,
|
||||
"ClutterBlurEffect (base pipeline)");
|
||||
|
||||
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
|
||||
box_blur_glsl_declarations,
|
||||
NULL);
|
||||
cogl_snippet_set_replace (snippet, box_blur_glsl_shader);
|
||||
cogl_pipeline_add_layer_snippet (klass->base_pipeline, 0, snippet);
|
||||
g_object_unref (snippet);
|
||||
|
||||
cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0);
|
||||
}
|
||||
|
||||
priv->pipeline = cogl_pipeline_copy (klass->base_pipeline);
|
||||
|
||||
priv->pixel_step_uniform =
|
||||
cogl_pipeline_get_uniform_location (priv->pipeline, "pixel_step");
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_blur_effect_new:
|
||||
*
|
||||
* Creates a new #ClutterBlurEffect to be used with
|
||||
* [method@Clutter.Actor.add_effect]
|
||||
*
|
||||
* Return value: the newly created #ClutterBlurEffect or %NULL
|
||||
*/
|
||||
ClutterEffect *
|
||||
clutter_blur_effect_new (void)
|
||||
{
|
||||
return g_object_new (CLUTTER_TYPE_BLUR_EFFECT, NULL);
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-effect.h"
|
||||
#include "clutter/clutter-offscreen-effect.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_BLUR_EFFECT (clutter_blur_effect_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterBlurEffect,
|
||||
clutter_blur_effect,
|
||||
CLUTTER, BLUR_EFFECT,
|
||||
ClutterOffscreenEffect)
|
||||
|
||||
struct _ClutterBlurEffectClass
|
||||
{
|
||||
ClutterOffscreenEffectClass parent_class;
|
||||
|
||||
CoglPipeline *base_pipeline;
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterEffect *clutter_blur_effect_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Endless OS Foundation, LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _ClutterBlur ClutterBlur;
|
||||
|
||||
ClutterBlur * clutter_blur_new (CoglTexture *texture,
|
||||
float radius);
|
||||
|
||||
void clutter_blur_apply (ClutterBlur *blur);
|
||||
|
||||
CoglTexture * clutter_blur_get_texture (ClutterBlur *blur);
|
||||
|
||||
void clutter_blur_free (ClutterBlur *blur);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,435 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Endless OS Foundation, LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-blur-private.h"
|
||||
|
||||
#include "clutter/clutter-backend.h"
|
||||
|
||||
/**
|
||||
* ClutterBlur:
|
||||
*
|
||||
* Blur textures
|
||||
*
|
||||
* #ClutterBlur is a moderately fast gaussian blur implementation.
|
||||
*
|
||||
* # Optimizations
|
||||
*
|
||||
* There are a number of optimizations in place to make this blur implementation
|
||||
* real-time. All in all, the implementation performs best when using large
|
||||
* blur-radii that allow downscaling the texture to smaller sizes, at small
|
||||
* radii where no downscaling is possible this can easily halve the framerate.
|
||||
*
|
||||
* ## Multipass
|
||||
*
|
||||
* It is implemented in 2 passes: vertical and horizontal.
|
||||
*
|
||||
* ## Downscaling
|
||||
*
|
||||
* #ClutterBlur uses dynamic downscaling to speed up blurring. Downscaling
|
||||
* happens in factors of 2 (the image is downscaled either by 2, 4, 8, 16, …)
|
||||
* and depends on the blur radius, the texture size, among others.
|
||||
*
|
||||
* The texture is drawn into a downscaled framebuffer; the blur passes are
|
||||
* applied on the downscaled texture contents; and finally, the blurred
|
||||
* contents are drawn
|
||||
* upscaled again.
|
||||
*
|
||||
* ## Hardware Interpolation
|
||||
*
|
||||
* This blur implementation cuts down the number of sampling operations by
|
||||
* exploiting the hardware interpolation that is performed when sampling between
|
||||
* pixel boundaries. This technique is described at:
|
||||
*
|
||||
* http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
|
||||
*
|
||||
* ## Incremental gauss-factor calculation
|
||||
*
|
||||
* The kernel values for the gaussian kernel are computed incrementally instead
|
||||
* of running the expensive calculations multiple times inside the blur shader.
|
||||
* The implementation is based on the algorithm presented by K. Turkowski in
|
||||
* GPU Gems 3, chapter 40:
|
||||
*
|
||||
* https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch40.html
|
||||
*
|
||||
*/
|
||||
|
||||
static const char *gaussian_blur_glsl_declarations =
|
||||
"uniform float sigma; \n"
|
||||
"uniform float pixel_step; \n"
|
||||
"uniform vec2 direction; \n";
|
||||
|
||||
static const char *gaussian_blur_glsl =
|
||||
" vec2 uv = vec2 (cogl_tex_coord.st); \n"
|
||||
" \n"
|
||||
" vec3 gauss_coefficient; \n"
|
||||
" gauss_coefficient.x = 1.0 / (sqrt (2.0 * 3.14159265) * sigma); \n"
|
||||
" gauss_coefficient.y = exp (-0.5 / (sigma * sigma)); \n"
|
||||
" gauss_coefficient.z = gauss_coefficient.y * gauss_coefficient.y; \n"
|
||||
" \n"
|
||||
" float gauss_coefficient_total = gauss_coefficient.x; \n"
|
||||
" \n"
|
||||
" vec4 ret = texture2D (cogl_sampler, uv) * gauss_coefficient.x; \n"
|
||||
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
|
||||
" \n"
|
||||
" int n_steps = int (ceil (1.5 * sigma)) * 2; \n"
|
||||
" \n"
|
||||
" for (int i = 1; i <= n_steps; i += 2) { \n"
|
||||
" float coefficient_subtotal = gauss_coefficient.x; \n"
|
||||
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
|
||||
" coefficient_subtotal += gauss_coefficient.x; \n"
|
||||
" \n"
|
||||
" float gauss_ratio = gauss_coefficient.x / coefficient_subtotal; \n"
|
||||
" \n"
|
||||
" float foffset = float (i) + gauss_ratio; \n"
|
||||
" vec2 offset = direction * foffset * pixel_step; \n"
|
||||
" \n"
|
||||
" ret += texture2D (cogl_sampler, uv + offset) * coefficient_subtotal; \n"
|
||||
" ret += texture2D (cogl_sampler, uv - offset) * coefficient_subtotal; \n"
|
||||
" \n"
|
||||
" gauss_coefficient_total += 2.0 * coefficient_subtotal; \n"
|
||||
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
|
||||
" } \n"
|
||||
" \n"
|
||||
" cogl_texel = ret / gauss_coefficient_total; \n";
|
||||
|
||||
#define MIN_DOWNSCALE_SIZE 256.f
|
||||
#define MAX_SIGMA 6.f
|
||||
|
||||
enum
|
||||
{
|
||||
VERTICAL,
|
||||
HORIZONTAL,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglPipeline *pipeline;
|
||||
CoglTexture *texture;
|
||||
int orientation;
|
||||
} BlurPass;
|
||||
|
||||
struct _ClutterBlur
|
||||
{
|
||||
CoglTexture *source_texture;
|
||||
float sigma;
|
||||
float downscale_factor;
|
||||
|
||||
BlurPass pass[2];
|
||||
};
|
||||
|
||||
static CoglPipeline*
|
||||
create_blur_pipeline (CoglContext *ctx)
|
||||
{
|
||||
static CoglPipelineKey blur_pipeline_key = "clutter-blur-pipeline-private";
|
||||
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_static_name (blur_pipeline, "ClutterBlur");
|
||||
cogl_pipeline_set_layer_null_texture (blur_pipeline, 0);
|
||||
cogl_pipeline_set_layer_filters (blur_pipeline,
|
||||
0,
|
||||
COGL_PIPELINE_FILTER_LINEAR,
|
||||
COGL_PIPELINE_FILTER_LINEAR);
|
||||
cogl_pipeline_set_layer_wrap_mode (blur_pipeline,
|
||||
0,
|
||||
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
||||
|
||||
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
|
||||
gaussian_blur_glsl_declarations,
|
||||
NULL);
|
||||
cogl_snippet_set_replace (snippet, gaussian_blur_glsl);
|
||||
cogl_pipeline_add_layer_snippet (blur_pipeline, 0, snippet);
|
||||
g_object_unref (snippet);
|
||||
|
||||
cogl_context_set_named_pipeline (ctx, &blur_pipeline_key, blur_pipeline);
|
||||
}
|
||||
|
||||
return cogl_pipeline_copy (blur_pipeline);
|
||||
}
|
||||
|
||||
static void
|
||||
update_blur_uniforms (ClutterBlur *blur,
|
||||
BlurPass *pass)
|
||||
{
|
||||
gboolean vertical = pass->orientation == VERTICAL;
|
||||
int sigma_uniform;
|
||||
int pixel_step_uniform;
|
||||
int direction_uniform;
|
||||
|
||||
pixel_step_uniform =
|
||||
cogl_pipeline_get_uniform_location (pass->pipeline, "pixel_step");
|
||||
if (pixel_step_uniform > -1)
|
||||
{
|
||||
float pixel_step;
|
||||
|
||||
if (vertical)
|
||||
pixel_step = 1.f / cogl_texture_get_height (pass->texture);
|
||||
else
|
||||
pixel_step = 1.f / cogl_texture_get_width (pass->texture);
|
||||
|
||||
cogl_pipeline_set_uniform_1f (pass->pipeline,
|
||||
pixel_step_uniform,
|
||||
pixel_step);
|
||||
}
|
||||
|
||||
sigma_uniform = cogl_pipeline_get_uniform_location (pass->pipeline, "sigma");
|
||||
if (sigma_uniform > -1)
|
||||
{
|
||||
cogl_pipeline_set_uniform_1f (pass->pipeline,
|
||||
sigma_uniform,
|
||||
blur->sigma / blur->downscale_factor);
|
||||
}
|
||||
|
||||
direction_uniform =
|
||||
cogl_pipeline_get_uniform_location (pass->pipeline, "direction");
|
||||
if (direction_uniform > -1)
|
||||
{
|
||||
gboolean horizontal = !vertical;
|
||||
float direction[2] = {
|
||||
horizontal,
|
||||
vertical,
|
||||
};
|
||||
|
||||
cogl_pipeline_set_uniform_float (pass->pipeline,
|
||||
direction_uniform,
|
||||
2, 1,
|
||||
direction);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
create_fbo (ClutterBlur *blur,
|
||||
CoglContext *ctx,
|
||||
BlurPass *pass)
|
||||
{
|
||||
float scaled_height;
|
||||
float scaled_width;
|
||||
float height;
|
||||
float width;
|
||||
|
||||
g_clear_object (&pass->texture);
|
||||
g_clear_object (&pass->framebuffer);
|
||||
|
||||
width = cogl_texture_get_width (blur->source_texture);
|
||||
height = cogl_texture_get_height (blur->source_texture);
|
||||
scaled_width = floorf (width / blur->downscale_factor);
|
||||
scaled_height = floorf (height / blur->downscale_factor);
|
||||
|
||||
pass->texture = cogl_texture_2d_new_with_size (ctx,
|
||||
(int) scaled_width,
|
||||
(int) 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)
|
||||
{
|
||||
CoglContext *context = cogl_texture_get_context (texture);
|
||||
pass->orientation = orientation;
|
||||
pass->pipeline = create_blur_pipeline (context);
|
||||
cogl_pipeline_set_layer_texture (pass->pipeline, 0, texture);
|
||||
|
||||
if (!create_fbo (blur, context, pass))
|
||||
return FALSE;
|
||||
|
||||
update_blur_uniforms (blur, pass);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static float
|
||||
calculate_downscale_factor (float width,
|
||||
float height,
|
||||
float sigma)
|
||||
{
|
||||
float downscale_factor = 1.f;
|
||||
float scaled_width = width;
|
||||
float scaled_height = height;
|
||||
float scaled_sigma = sigma;
|
||||
|
||||
/* This is the algorithm used by Firefox; keep downscaling until either the
|
||||
* blur radius is lower than the threshold, or the downscaled texture is too
|
||||
* small.
|
||||
*/
|
||||
while (scaled_sigma > MAX_SIGMA &&
|
||||
scaled_width > MIN_DOWNSCALE_SIZE &&
|
||||
scaled_height > MIN_DOWNSCALE_SIZE)
|
||||
{
|
||||
downscale_factor *= 2.f;
|
||||
|
||||
scaled_width = width / downscale_factor;
|
||||
scaled_height = height / downscale_factor;
|
||||
scaled_sigma = sigma / downscale_factor;
|
||||
}
|
||||
|
||||
return downscale_factor;
|
||||
}
|
||||
|
||||
static void
|
||||
apply_blur_pass (BlurPass *pass)
|
||||
{
|
||||
CoglColor transparent;
|
||||
|
||||
cogl_color_init_from_4f (&transparent, 0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
cogl_framebuffer_clear (pass->framebuffer,
|
||||
COGL_BUFFER_BIT_COLOR,
|
||||
&transparent);
|
||||
|
||||
cogl_framebuffer_draw_rectangle (pass->framebuffer,
|
||||
pass->pipeline,
|
||||
0, 0,
|
||||
cogl_texture_get_width (pass->texture),
|
||||
cogl_texture_get_height (pass->texture));
|
||||
}
|
||||
|
||||
static void
|
||||
clear_blur_pass (BlurPass *pass)
|
||||
{
|
||||
g_clear_object (&pass->pipeline);
|
||||
g_clear_object (&pass->texture);
|
||||
g_clear_object (&pass->framebuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_blur_new:
|
||||
* @texture: a #CoglTexture
|
||||
* @sigma: blur sigma
|
||||
*
|
||||
* Creates a new #ClutterBlur.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): A newly created #ClutterBlur
|
||||
*/
|
||||
ClutterBlur *
|
||||
clutter_blur_new (CoglTexture *texture,
|
||||
float radius)
|
||||
{
|
||||
ClutterBlur *blur;
|
||||
unsigned int height;
|
||||
unsigned int width;
|
||||
BlurPass *hpass;
|
||||
BlurPass *vpass;
|
||||
|
||||
g_return_val_if_fail (texture != NULL, NULL);
|
||||
g_return_val_if_fail (radius >= 0.0f, NULL);
|
||||
|
||||
width = cogl_texture_get_width (texture);
|
||||
height = cogl_texture_get_height (texture);
|
||||
|
||||
blur = g_new0 (ClutterBlur, 1);
|
||||
blur->sigma = radius / 2.0f;
|
||||
blur->source_texture = g_object_ref (texture);
|
||||
blur->downscale_factor = calculate_downscale_factor (width,
|
||||
height,
|
||||
blur->sigma);
|
||||
|
||||
if (G_APPROX_VALUE (blur->sigma, 0.0f, FLT_EPSILON))
|
||||
goto out;
|
||||
|
||||
vpass = &blur->pass[VERTICAL];
|
||||
hpass = &blur->pass[HORIZONTAL];
|
||||
|
||||
if (!setup_blur_pass (blur, vpass, VERTICAL, texture) ||
|
||||
!setup_blur_pass (blur, hpass, HORIZONTAL, vpass->texture))
|
||||
{
|
||||
clutter_blur_free (blur);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
return g_steal_pointer (&blur);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_blur_apply:
|
||||
* @blur: a #ClutterBlur
|
||||
*
|
||||
* Applies the blur. The resulting texture can be retrieved by
|
||||
* [method@Clutter.Blur.get_texture].
|
||||
*/
|
||||
void
|
||||
clutter_blur_apply (ClutterBlur *blur)
|
||||
{
|
||||
if (G_APPROX_VALUE (blur->sigma, 0.0, FLT_EPSILON))
|
||||
return;
|
||||
|
||||
apply_blur_pass (&blur->pass[VERTICAL]);
|
||||
apply_blur_pass (&blur->pass[HORIZONTAL]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_blur_get_texture:
|
||||
* @blur: a #ClutterBlur
|
||||
*
|
||||
* Retrieves the texture where the blurred contents are stored. The
|
||||
* contents are undefined until [method@Clutter.Blur.apply] is called.
|
||||
*
|
||||
* Returns: (transfer none): a #CoglTexture
|
||||
*/
|
||||
CoglTexture *
|
||||
clutter_blur_get_texture (ClutterBlur *blur)
|
||||
{
|
||||
if (G_APPROX_VALUE (blur->sigma, 0.0, FLT_EPSILON))
|
||||
return blur->source_texture;
|
||||
else
|
||||
return blur->pass[HORIZONTAL].texture;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_blur_free:
|
||||
* @blur: A #ClutterBlur
|
||||
*
|
||||
* Frees @blur.
|
||||
*/
|
||||
void
|
||||
clutter_blur_free (ClutterBlur *blur)
|
||||
{
|
||||
g_assert (blur);
|
||||
|
||||
clear_blur_pass (&blur->pass[VERTICAL]);
|
||||
clear_blur_pass (&blur->pass[HORIZONTAL]);
|
||||
g_clear_object (&blur->source_texture);
|
||||
g_free (blur);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2009 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*
|
||||
* Based on the NBTK NbtkBoxLayout actor by:
|
||||
* Thomas Wood <thomas.wood@intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-layout-manager.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_BOX_LAYOUT (clutter_box_layout_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterBoxLayout,
|
||||
clutter_box_layout,
|
||||
CLUTTER, BOX_LAYOUT,
|
||||
ClutterLayoutManager)
|
||||
|
||||
struct _ClutterBoxLayoutClass
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterLayoutManagerClass parent_class;
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterLayoutManager * clutter_box_layout_new (void);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_box_layout_set_orientation (ClutterBoxLayout *layout,
|
||||
ClutterOrientation orientation);
|
||||
CLUTTER_EXPORT
|
||||
ClutterOrientation clutter_box_layout_get_orientation (ClutterBoxLayout *layout);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_box_layout_set_spacing (ClutterBoxLayout *layout,
|
||||
guint spacing);
|
||||
CLUTTER_EXPORT
|
||||
guint clutter_box_layout_get_spacing (ClutterBoxLayout *layout);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_box_layout_set_homogeneous (ClutterBoxLayout *layout,
|
||||
gboolean homogeneous);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_box_layout_get_homogeneous (ClutterBoxLayout *layout);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,598 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010-2012 Inclusive Design Research Centre, OCAD University.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Joseph Scheuhammer <clown@alum.mit.edu>
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterBrightnessContrastEffect:
|
||||
*
|
||||
* Increase/decrease brightness and/or contrast of actor.
|
||||
*
|
||||
* #ClutterBrightnessContrastEffect is a sub-class of #ClutterEffect that
|
||||
* changes the overall brightness of a #ClutterActor.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
|
||||
#include "clutter/clutter-brightness-contrast-effect.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-enum-types.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
typedef struct _ClutterBrightnessContrastEffectPrivate
|
||||
{
|
||||
/* Brightness and contrast changes. */
|
||||
gfloat brightness_red;
|
||||
gfloat brightness_green;
|
||||
gfloat brightness_blue;
|
||||
|
||||
gfloat contrast_red;
|
||||
gfloat contrast_green;
|
||||
gfloat contrast_blue;
|
||||
|
||||
gint brightness_multiplier_uniform;
|
||||
gint brightness_offset_uniform;
|
||||
gint contrast_uniform;
|
||||
|
||||
CoglPipeline *pipeline;
|
||||
} ClutterBrightnessContrastEffectPrivate;
|
||||
|
||||
|
||||
/* Brightness effects in GLSL.
|
||||
*/
|
||||
static const gchar *brightness_contrast_decls =
|
||||
"uniform vec3 brightness_multiplier;\n"
|
||||
"uniform vec3 brightness_offset;\n"
|
||||
"uniform vec3 contrast;\n";
|
||||
|
||||
static const gchar *brightness_contrast_source =
|
||||
/* Apply the brightness. The brightness_offset is multiplied by the
|
||||
alpha to keep the color pre-multiplied */
|
||||
"cogl_color_out.rgb = (cogl_color_out.rgb * brightness_multiplier +\n"
|
||||
" brightness_offset * cogl_color_out.a);\n"
|
||||
/* Apply the contrast */
|
||||
"cogl_color_out.rgb = ((cogl_color_out.rgb - 0.5 * cogl_color_out.a) *\n"
|
||||
" contrast + 0.5 * cogl_color_out.a);\n";
|
||||
|
||||
static const CoglColor no_brightness_change = { 0x7f, 0x7f, 0x7f, 0xff };
|
||||
static const CoglColor no_contrast_change = { 0x7f, 0x7f, 0x7f, 0xff };
|
||||
static const gfloat no_change = 0.0f;
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_BRIGHTNESS,
|
||||
PROP_CONTRAST,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterBrightnessContrastEffect,
|
||||
clutter_brightness_contrast_effect,
|
||||
CLUTTER_TYPE_OFFSCREEN_EFFECT)
|
||||
|
||||
static gboolean
|
||||
will_have_no_effect (ClutterBrightnessContrastEffect *self)
|
||||
{
|
||||
ClutterBrightnessContrastEffectPrivate *priv =
|
||||
clutter_brightness_contrast_effect_get_instance_private (self);
|
||||
|
||||
return (G_APPROX_VALUE (priv->brightness_red, no_change, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (priv->brightness_green, no_change, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (priv->brightness_blue, no_change, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (priv->contrast_red, no_change, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (priv->contrast_green, no_change, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (priv->contrast_blue, no_change, FLT_EPSILON));
|
||||
}
|
||||
|
||||
static CoglPipeline *
|
||||
clutter_brightness_contrast_effect_create_pipeline (ClutterOffscreenEffect *effect,
|
||||
CoglTexture *texture)
|
||||
{
|
||||
ClutterBrightnessContrastEffect *self =
|
||||
CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
|
||||
ClutterBrightnessContrastEffectPrivate *priv =
|
||||
clutter_brightness_contrast_effect_get_instance_private (self);
|
||||
|
||||
cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture);
|
||||
|
||||
return g_object_ref (priv->pipeline);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
|
||||
ClutterEffectClass *parent_class;
|
||||
|
||||
if (will_have_no_effect (self))
|
||||
return FALSE;
|
||||
|
||||
parent_class =
|
||||
CLUTTER_EFFECT_CLASS (clutter_brightness_contrast_effect_parent_class);
|
||||
|
||||
return parent_class->pre_paint (effect, node, paint_context);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_brightness_contrast_effect_dispose (GObject *gobject)
|
||||
{
|
||||
ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (gobject);
|
||||
ClutterBrightnessContrastEffectPrivate *priv =
|
||||
clutter_brightness_contrast_effect_get_instance_private (self);
|
||||
|
||||
g_clear_object (&priv->pipeline);
|
||||
|
||||
G_OBJECT_CLASS (clutter_brightness_contrast_effect_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_brightness_contrast_effect_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterBrightnessContrastEffect *effect = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_BRIGHTNESS:
|
||||
{
|
||||
const CoglColor *color = cogl_value_get_color (value);
|
||||
clutter_brightness_contrast_effect_set_brightness_full (effect,
|
||||
color->red / 127.0f - 1.0f,
|
||||
color->green / 127.0f - 1.0f,
|
||||
color->blue / 127.0f - 1.0f);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_CONTRAST:
|
||||
{
|
||||
const CoglColor *color = cogl_value_get_color (value);
|
||||
clutter_brightness_contrast_effect_set_contrast_full (effect,
|
||||
color->red / 127.0f - 1.0f,
|
||||
color->green / 127.0f - 1.0f,
|
||||
color->blue / 127.0f - 1.0f);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_brightness_contrast_effect_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterBrightnessContrastEffect *effect = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (gobject);
|
||||
ClutterBrightnessContrastEffectPrivate *priv =
|
||||
clutter_brightness_contrast_effect_get_instance_private (effect);
|
||||
CoglColor color;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_BRIGHTNESS:
|
||||
{
|
||||
color.red = (uint8_t) ((priv->brightness_red + 1.0f) * 127.0f);
|
||||
color.green = (uint8_t) ((priv->brightness_green + 1.0f) * 127.0f);
|
||||
color.blue = (uint8_t) ((priv->brightness_blue + 1.0f) * 127.0f);
|
||||
color.alpha = 0xff;
|
||||
|
||||
cogl_value_set_color (value, &color);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_CONTRAST:
|
||||
{
|
||||
color.red = (uint8_t) ((priv->contrast_red + 1.0f) * 127.0f);
|
||||
color.green = (uint8_t) ((priv->contrast_green + 1.0f) * 127.0f);
|
||||
color.blue = (uint8_t) ((priv->contrast_blue + 1.0f) * 127.0f);
|
||||
color.alpha = 0xff;
|
||||
|
||||
cogl_value_set_color (value, &color);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_brightness_contrast_effect_class_init (ClutterBrightnessContrastEffectClass *klass)
|
||||
{
|
||||
ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterOffscreenEffectClass *offscreen_class;
|
||||
|
||||
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
||||
offscreen_class->create_pipeline = clutter_brightness_contrast_effect_create_pipeline;
|
||||
|
||||
effect_class->pre_paint = clutter_brightness_contrast_effect_pre_paint;
|
||||
|
||||
gobject_class->set_property = clutter_brightness_contrast_effect_set_property;
|
||||
gobject_class->get_property = clutter_brightness_contrast_effect_get_property;
|
||||
gobject_class->dispose = clutter_brightness_contrast_effect_dispose;
|
||||
|
||||
/**
|
||||
* ClutterBrightnessContrastEffect:brightness:
|
||||
*
|
||||
* The brightness change to apply to the effect.
|
||||
*
|
||||
* This property uses a #CoglColor to represent the changes to each
|
||||
* color channel. The range is [ 0, 255 ], with 127 as the value used
|
||||
* to indicate no change; values smaller than 127 indicate a decrease
|
||||
* in brightness, and values larger than 127 indicate an increase in
|
||||
* brightness.
|
||||
*/
|
||||
obj_props[PROP_BRIGHTNESS] =
|
||||
cogl_param_spec_color ("brightness", NULL, NULL,
|
||||
&no_brightness_change,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterBrightnessContrastEffect:contrast:
|
||||
*
|
||||
* The contrast change to apply to the effect.
|
||||
*
|
||||
* This property uses a #CoglColor to represent the changes to each
|
||||
* color channel. The range is [ 0, 255 ], with 127 as the value used
|
||||
* to indicate no change; values smaller than 127 indicate a decrease
|
||||
* in contrast, and values larger than 127 indicate an increase in
|
||||
* contrast.
|
||||
*/
|
||||
obj_props[PROP_CONTRAST] =
|
||||
cogl_param_spec_color ("contrast", NULL, NULL,
|
||||
&no_contrast_change,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
get_brightness_values (gfloat value,
|
||||
gfloat *multiplier,
|
||||
gfloat *offset)
|
||||
{
|
||||
if (value < 0.0f)
|
||||
{
|
||||
*multiplier = 1.0f + value;
|
||||
*offset = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
*multiplier = 1.0f - value;
|
||||
*offset = value;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
update_uniforms (ClutterBrightnessContrastEffect *self)
|
||||
{
|
||||
ClutterBrightnessContrastEffectPrivate *priv =
|
||||
clutter_brightness_contrast_effect_get_instance_private (self);
|
||||
|
||||
if (priv->brightness_multiplier_uniform > -1 &&
|
||||
priv->brightness_offset_uniform > -1)
|
||||
{
|
||||
float brightness_multiplier[3];
|
||||
float brightness_offset[3];
|
||||
|
||||
get_brightness_values (priv->brightness_red,
|
||||
brightness_multiplier + 0,
|
||||
brightness_offset + 0);
|
||||
get_brightness_values (priv->brightness_green,
|
||||
brightness_multiplier + 1,
|
||||
brightness_offset + 1);
|
||||
get_brightness_values (priv->brightness_blue,
|
||||
brightness_multiplier + 2,
|
||||
brightness_offset + 2);
|
||||
|
||||
cogl_pipeline_set_uniform_float (priv->pipeline,
|
||||
priv->brightness_multiplier_uniform,
|
||||
3, /* n_components */
|
||||
1, /* count */
|
||||
brightness_multiplier);
|
||||
cogl_pipeline_set_uniform_float (priv->pipeline,
|
||||
priv->brightness_offset_uniform,
|
||||
3, /* n_components */
|
||||
1, /* count */
|
||||
brightness_offset);
|
||||
}
|
||||
|
||||
if (priv->contrast_uniform > -1)
|
||||
{
|
||||
float contrast[3] = {
|
||||
(float) tan ((priv->contrast_red + 1) * G_PI_4),
|
||||
(float) tan ((priv->contrast_green + 1) * G_PI_4),
|
||||
(float) tan ((priv->contrast_blue + 1) * G_PI_4)
|
||||
};
|
||||
|
||||
cogl_pipeline_set_uniform_float (priv->pipeline,
|
||||
priv->contrast_uniform,
|
||||
3, /* n_components */
|
||||
1, /* count */
|
||||
contrast);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_brightness_contrast_effect_init (ClutterBrightnessContrastEffect *self)
|
||||
{
|
||||
ClutterBrightnessContrastEffectClass *klass;
|
||||
ClutterBrightnessContrastEffectPrivate *priv =
|
||||
clutter_brightness_contrast_effect_get_instance_private (self);
|
||||
|
||||
priv->brightness_red = no_change;
|
||||
priv->brightness_green = no_change;
|
||||
priv->brightness_blue = no_change;
|
||||
|
||||
priv->contrast_red = no_change;
|
||||
priv->contrast_green = no_change;
|
||||
priv->contrast_blue = no_change;
|
||||
|
||||
klass = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_GET_CLASS (self);
|
||||
|
||||
if (G_UNLIKELY (klass->base_pipeline == NULL))
|
||||
{
|
||||
CoglSnippet *snippet;
|
||||
ClutterContext *context = _clutter_context_get_default ();
|
||||
ClutterBackend *backend = clutter_context_get_backend (context);
|
||||
CoglContext *cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
|
||||
klass->base_pipeline = cogl_pipeline_new (cogl_context);
|
||||
cogl_pipeline_set_static_name (klass->base_pipeline,
|
||||
"ClutterBrightnessContrast");
|
||||
|
||||
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
|
||||
brightness_contrast_decls,
|
||||
brightness_contrast_source);
|
||||
cogl_pipeline_add_snippet (klass->base_pipeline, snippet);
|
||||
g_object_unref (snippet);
|
||||
|
||||
cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0);
|
||||
}
|
||||
|
||||
priv->pipeline = cogl_pipeline_copy (klass->base_pipeline);
|
||||
|
||||
priv->brightness_multiplier_uniform =
|
||||
cogl_pipeline_get_uniform_location (priv->pipeline,
|
||||
"brightness_multiplier");
|
||||
priv->brightness_offset_uniform =
|
||||
cogl_pipeline_get_uniform_location (priv->pipeline,
|
||||
"brightness_offset");
|
||||
priv->contrast_uniform =
|
||||
cogl_pipeline_get_uniform_location (priv->pipeline, "contrast");
|
||||
|
||||
update_uniforms (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_brightness_contrast_effect_new:
|
||||
*
|
||||
* Creates a new #ClutterBrightnessContrastEffect to be used with
|
||||
* [method@Clutter.Actor.add_effect]
|
||||
*
|
||||
* Return value: (transfer full): the newly created
|
||||
* #ClutterBrightnessContrastEffect or %NULL. Use g_object_unref() when
|
||||
* done.
|
||||
*/
|
||||
ClutterEffect *
|
||||
clutter_brightness_contrast_effect_new (void)
|
||||
{
|
||||
return g_object_new (CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_brightness_contrast_effect_set_brightness_full:
|
||||
* @effect: a #ClutterBrightnessContrastEffect
|
||||
* @red: red component of the change in brightness
|
||||
* @green: green component of the change in brightness
|
||||
* @blue: blue component of the change in brightness
|
||||
*
|
||||
* The range for each component is [-1.0, 1.0] where 0.0 designates no change,
|
||||
* values below 0.0 mean a decrease in brightness, and values above indicate
|
||||
* an increase.
|
||||
*/
|
||||
void
|
||||
clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContrastEffect *effect,
|
||||
gfloat red,
|
||||
gfloat green,
|
||||
gfloat blue)
|
||||
{
|
||||
ClutterBrightnessContrastEffectPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
|
||||
|
||||
priv = clutter_brightness_contrast_effect_get_instance_private (effect);
|
||||
if (G_APPROX_VALUE (red, priv->brightness_red, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (green, priv->brightness_green, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (blue, priv->brightness_blue, FLT_EPSILON))
|
||||
return;
|
||||
|
||||
priv->brightness_red = red;
|
||||
priv->brightness_green = green;
|
||||
priv->brightness_blue = blue;
|
||||
|
||||
update_uniforms (effect);
|
||||
|
||||
clutter_effect_queue_repaint (CLUTTER_EFFECT (effect));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_BRIGHTNESS]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_brightness_contrast_effect_get_brightness:
|
||||
* @effect: a #ClutterBrightnessContrastEffect
|
||||
* @red: (out) (allow-none): return location for red component of the
|
||||
* change in brightness
|
||||
* @green: (out) (allow-none): return location for green component of the
|
||||
* change in brightness
|
||||
* @blue: (out) (allow-none): return location for blue component of the
|
||||
* change in brightness
|
||||
*
|
||||
* Retrieves the change in brightness used by @effect.
|
||||
*/
|
||||
void
|
||||
clutter_brightness_contrast_effect_get_brightness (ClutterBrightnessContrastEffect *effect,
|
||||
gfloat *red,
|
||||
gfloat *green,
|
||||
gfloat *blue)
|
||||
{
|
||||
ClutterBrightnessContrastEffectPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
|
||||
|
||||
priv = clutter_brightness_contrast_effect_get_instance_private (effect);
|
||||
if (red != NULL)
|
||||
*red = priv->brightness_red;
|
||||
|
||||
if (green != NULL)
|
||||
*green = priv->brightness_green;
|
||||
|
||||
if (blue != NULL)
|
||||
*blue = priv->brightness_blue;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_brightness_contrast_effect_set_brightness:
|
||||
* @effect: a #ClutterBrightnessContrastEffect
|
||||
* @brightness: the brightness change for all three components (r, g, b)
|
||||
*
|
||||
* The range of @brightness is [-1.0, 1.0], where 0.0 designates no change;
|
||||
* a value below 0.0 indicates a decrease in brightness; and a value
|
||||
* above 0.0 indicates an increase of brightness.
|
||||
*/
|
||||
void
|
||||
clutter_brightness_contrast_effect_set_brightness (ClutterBrightnessContrastEffect *effect,
|
||||
gfloat brightness)
|
||||
{
|
||||
clutter_brightness_contrast_effect_set_brightness_full (effect,
|
||||
brightness,
|
||||
brightness,
|
||||
brightness);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_brightness_contrast_effect_set_contrast_full:
|
||||
* @effect: a #ClutterBrightnessContrastEffect
|
||||
* @red: red component of the change in contrast
|
||||
* @green: green component of the change in contrast
|
||||
* @blue: blue component of the change in contrast
|
||||
*
|
||||
* The range for each component is [-1.0, 1.0] where 0.0 designates no change,
|
||||
* values below 0.0 mean a decrease in contrast, and values above indicate
|
||||
* an increase.
|
||||
*/
|
||||
void
|
||||
clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastEffect *effect,
|
||||
gfloat red,
|
||||
gfloat green,
|
||||
gfloat blue)
|
||||
{
|
||||
ClutterBrightnessContrastEffectPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
|
||||
|
||||
priv = clutter_brightness_contrast_effect_get_instance_private (effect);
|
||||
if (G_APPROX_VALUE (red, priv->contrast_red, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (green, priv->contrast_green, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (blue, priv->contrast_blue, FLT_EPSILON))
|
||||
return;
|
||||
|
||||
priv->contrast_red = red;
|
||||
priv->contrast_green = green;
|
||||
priv->contrast_blue = blue;
|
||||
|
||||
update_uniforms (effect);
|
||||
|
||||
clutter_effect_queue_repaint (CLUTTER_EFFECT (effect));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_CONTRAST]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_brightness_contrast_effect_get_contrast:
|
||||
* @effect: a #ClutterBrightnessContrastEffect
|
||||
* @red: (out) (allow-none): return location for red component of the
|
||||
* change in contrast
|
||||
* @green: (out) (allow-none): return location for green component of the
|
||||
* change in contrast
|
||||
* @blue: (out) (allow-none): return location for blue component of the
|
||||
* change in contrast
|
||||
*
|
||||
* Retrieves the contrast value used by @effect.
|
||||
*/
|
||||
void
|
||||
clutter_brightness_contrast_effect_get_contrast (ClutterBrightnessContrastEffect *effect,
|
||||
gfloat *red,
|
||||
gfloat *green,
|
||||
gfloat *blue)
|
||||
{
|
||||
ClutterBrightnessContrastEffectPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
|
||||
|
||||
priv = clutter_brightness_contrast_effect_get_instance_private (effect);
|
||||
if (red != NULL)
|
||||
*red = priv->contrast_red;
|
||||
|
||||
if (green != NULL)
|
||||
*green = priv->contrast_green;
|
||||
|
||||
if (blue != NULL)
|
||||
*blue = priv->contrast_blue;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_brightness_contrast_effect_set_contrast:
|
||||
* @effect: a #ClutterBrightnessContrastEffect
|
||||
* @contrast: contrast change for all three channels
|
||||
*
|
||||
* The range for @contrast is [-1.0, 1.0], where 0.0 designates no change;
|
||||
* a value below 0.0 indicates a decrease in contrast; and a value above
|
||||
* 0.0 indicates an increase.
|
||||
*/
|
||||
void
|
||||
clutter_brightness_contrast_effect_set_contrast (ClutterBrightnessContrastEffect *effect,
|
||||
gfloat contrast)
|
||||
{
|
||||
clutter_brightness_contrast_effect_set_contrast_full (effect,
|
||||
contrast,
|
||||
contrast,
|
||||
contrast);
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010-2012 Inclusive Design Research Centre, OCAD University.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Joseph Scheuhammer <clown@alum.mit.edu>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-effect.h"
|
||||
#include "clutter/clutter-offscreen-effect.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT (clutter_brightness_contrast_effect_get_type ())
|
||||
|
||||
|
||||
struct _ClutterBrightnessContrastEffectClass
|
||||
{
|
||||
ClutterOffscreenEffectClass parent_class;
|
||||
|
||||
CoglPipeline *base_pipeline;
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterBrightnessContrastEffect,
|
||||
clutter_brightness_contrast_effect,
|
||||
CLUTTER, BRIGHTNESS_CONTRAST_EFFECT,
|
||||
ClutterOffscreenEffect)
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterEffect * clutter_brightness_contrast_effect_new (void);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContrastEffect *effect,
|
||||
float red,
|
||||
float green,
|
||||
float blue);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_brightness_contrast_effect_set_brightness (ClutterBrightnessContrastEffect *effect,
|
||||
float brightness);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_brightness_contrast_effect_get_brightness (ClutterBrightnessContrastEffect *effect,
|
||||
float *red,
|
||||
float *green,
|
||||
float *blue);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastEffect *effect,
|
||||
float red,
|
||||
float green,
|
||||
float blue);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_brightness_contrast_effect_set_contrast (ClutterBrightnessContrastEffect *effect,
|
||||
float contrast);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_brightness_contrast_effect_get_contrast (ClutterBrightnessContrastEffect *effect,
|
||||
float *red,
|
||||
float *green,
|
||||
float *blue);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,786 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterClickAction:
|
||||
*
|
||||
* Action for clickable actors
|
||||
*
|
||||
* #ClutterClickAction is a sub-class of [class@Action] that implements
|
||||
* the logic for clickable actors, by using the low level events of
|
||||
* [class@Actor], such as [signal@Actor::button-press-event] and
|
||||
* [signal@Actor::button-release-event], to synthesize the high level
|
||||
* [signal@ClickAction::clicked] signal.
|
||||
*
|
||||
* To use #ClutterClickAction you just need to apply it to a [class@Actor]
|
||||
* using [method@Actor.add_action] and connect to the
|
||||
* [signal@ClickAction::clicked] signal:
|
||||
*
|
||||
* ```c
|
||||
* ClutterAction *action = clutter_click_action_new ();
|
||||
*
|
||||
* clutter_actor_add_action (actor, action);
|
||||
*
|
||||
* g_signal_connect (action, "clicked", G_CALLBACK (on_clicked), NULL);
|
||||
* ```
|
||||
*
|
||||
* #ClutterClickAction also supports long press gestures: a long press is
|
||||
* activated if the pointer remains pressed within a certain threshold (as
|
||||
* defined by the [property@ClickAction:long-press-threshold] property) for a
|
||||
* minimum amount of time (as the defined by the
|
||||
* [property@ClickAction:long-press-duration] property).
|
||||
* The [signal@ClickAction::long-press] signal is emitted multiple times,
|
||||
* using different [enum@LongPressState] values; to handle long presses
|
||||
* you should connect to the [signal@ClickAction::long-press] signal and
|
||||
* handle the different states:
|
||||
*
|
||||
* ```c
|
||||
* static gboolean
|
||||
* on_long_press (ClutterClickAction *action,
|
||||
* ClutterActor *actor,
|
||||
* ClutterLongPressState state)
|
||||
* {
|
||||
* switch (state)
|
||||
* {
|
||||
* case CLUTTER_LONG_PRESS_QUERY:
|
||||
* // return TRUE if the actor should support long press
|
||||
* // gestures, and FALSE otherwise; this state will be
|
||||
* // emitted on button presses
|
||||
* return TRUE;
|
||||
*
|
||||
* case CLUTTER_LONG_PRESS_ACTIVATE:
|
||||
* // this state is emitted if the minimum duration has
|
||||
* // been reached without the gesture being cancelled.
|
||||
* // the return value is not used
|
||||
* return TRUE;
|
||||
*
|
||||
* case CLUTTER_LONG_PRESS_CANCEL:
|
||||
* // this state is emitted if the long press was cancelled;
|
||||
* // for instance, the pointer went outside the actor or the
|
||||
* // allowed threshold, or the button was released before
|
||||
* // the minimum duration was reached. the return value is
|
||||
* // not used
|
||||
* return FALSE;
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-click-action.h"
|
||||
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-enum-types.h"
|
||||
#include "clutter/clutter-marshal.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
struct _ClutterClickActionPrivate
|
||||
{
|
||||
ClutterActor *stage;
|
||||
|
||||
guint long_press_id;
|
||||
|
||||
gint long_press_threshold;
|
||||
gint long_press_duration;
|
||||
gint drag_threshold;
|
||||
|
||||
guint press_button;
|
||||
ClutterInputDevice *press_device;
|
||||
ClutterEventSequence *press_sequence;
|
||||
ClutterModifierType modifier_state;
|
||||
gfloat press_x;
|
||||
gfloat press_y;
|
||||
|
||||
guint is_held : 1;
|
||||
guint is_pressed : 1;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_HELD,
|
||||
PROP_PRESSED,
|
||||
PROP_LONG_PRESS_THRESHOLD,
|
||||
PROP_LONG_PRESS_DURATION,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST] = { NULL, };
|
||||
|
||||
enum
|
||||
{
|
||||
CLICKED,
|
||||
LONG_PRESS,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint click_signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterClickAction, clutter_click_action, CLUTTER_TYPE_ACTION)
|
||||
|
||||
static inline void
|
||||
click_action_set_pressed (ClutterClickAction *action,
|
||||
gboolean is_pressed)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
|
||||
is_pressed = !!is_pressed;
|
||||
|
||||
if (priv->is_pressed == is_pressed)
|
||||
return;
|
||||
|
||||
priv->is_pressed = is_pressed;
|
||||
g_object_notify_by_pspec (G_OBJECT (action), obj_props[PROP_PRESSED]);
|
||||
}
|
||||
|
||||
static inline void
|
||||
click_action_set_held (ClutterClickAction *action,
|
||||
gboolean is_held)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
|
||||
is_held = !!is_held;
|
||||
|
||||
if (priv->is_held == is_held)
|
||||
return;
|
||||
|
||||
priv->is_held = is_held;
|
||||
g_object_notify_by_pspec (G_OBJECT (action), obj_props[PROP_HELD]);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
click_action_emit_long_press (gpointer data)
|
||||
{
|
||||
ClutterClickAction *action = data;
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
ClutterActor *actor;
|
||||
gboolean result;
|
||||
|
||||
priv->long_press_id = 0;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (data);
|
||||
|
||||
g_signal_emit (action, click_signals[LONG_PRESS], 0,
|
||||
actor,
|
||||
CLUTTER_LONG_PRESS_ACTIVATE,
|
||||
&result);
|
||||
|
||||
click_action_set_pressed (action, FALSE);
|
||||
click_action_set_held (action, FALSE);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
click_action_query_long_press (ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
ClutterActor *actor =
|
||||
clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
||||
ClutterContext *context = clutter_actor_get_context (actor);
|
||||
gboolean result = FALSE;
|
||||
gint timeout;
|
||||
|
||||
if (priv->long_press_duration < 0)
|
||||
{
|
||||
ClutterSettings *settings = clutter_context_get_settings (context);
|
||||
|
||||
g_object_get (settings,
|
||||
"long-press-duration", &timeout,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
timeout = priv->long_press_duration;
|
||||
|
||||
|
||||
g_signal_emit (action, click_signals[LONG_PRESS], 0,
|
||||
actor,
|
||||
CLUTTER_LONG_PRESS_QUERY,
|
||||
&result);
|
||||
|
||||
if (result)
|
||||
{
|
||||
g_clear_handle_id (&priv->long_press_id, g_source_remove);
|
||||
priv->long_press_id = g_timeout_add (timeout,
|
||||
click_action_emit_long_press,
|
||||
action);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
click_action_cancel_long_press (ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
|
||||
if (priv->long_press_id != 0)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
gboolean result;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
||||
|
||||
g_clear_handle_id (&priv->long_press_id, g_source_remove);
|
||||
|
||||
g_signal_emit (action, click_signals[LONG_PRESS], 0,
|
||||
actor,
|
||||
CLUTTER_LONG_PRESS_CANCEL,
|
||||
&result);
|
||||
}
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
event_within_drag_threshold (ClutterClickAction *click_action,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (click_action);
|
||||
float motion_x, motion_y;
|
||||
float delta_x, delta_y;
|
||||
|
||||
clutter_event_get_coords (event, &motion_x, &motion_y);
|
||||
|
||||
delta_x = ABS (motion_x - priv->press_x);
|
||||
delta_y = ABS (motion_y - priv->press_y);
|
||||
|
||||
return delta_x <= priv->drag_threshold && delta_y <= priv->drag_threshold;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_click_action_handle_event (ClutterAction *action,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
ClutterClickAction *click_action = CLUTTER_CLICK_ACTION (action);
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (click_action);
|
||||
ClutterActor *actor =
|
||||
clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
||||
ClutterContext *context = clutter_actor_get_context (actor);
|
||||
gboolean has_button = TRUE;
|
||||
ClutterModifierType modifier_state;
|
||||
ClutterActor *target;
|
||||
|
||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if (priv->press_sequence != NULL &&
|
||||
clutter_event_get_event_sequence (event) != priv->press_sequence)
|
||||
{
|
||||
click_action_set_held (click_action, FALSE);
|
||||
click_action_cancel_long_press (click_action);
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
switch (clutter_event_type (event))
|
||||
{
|
||||
case CLUTTER_TOUCH_BEGIN:
|
||||
has_button = FALSE;
|
||||
|
||||
G_GNUC_FALLTHROUGH;
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
if (priv->is_held)
|
||||
return CLUTTER_EVENT_STOP;
|
||||
|
||||
target = clutter_stage_get_device_actor (CLUTTER_STAGE (clutter_actor_get_stage (actor)),
|
||||
clutter_event_get_device (event),
|
||||
clutter_event_get_event_sequence (event));
|
||||
|
||||
if (!clutter_actor_contains (actor, target))
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
priv->press_button = has_button ? clutter_event_get_button (event) : 0;
|
||||
priv->press_device = clutter_event_get_device (event);
|
||||
priv->press_sequence = clutter_event_get_event_sequence (event);
|
||||
priv->modifier_state = clutter_event_get_state (event);
|
||||
clutter_event_get_coords (event, &priv->press_x, &priv->press_y);
|
||||
|
||||
if (priv->long_press_threshold < 0)
|
||||
{
|
||||
ClutterSettings *settings = clutter_context_get_settings (context);
|
||||
|
||||
g_object_get (settings,
|
||||
"dnd-drag-threshold", &priv->drag_threshold,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
priv->drag_threshold = priv->long_press_threshold;
|
||||
|
||||
if (priv->stage == NULL)
|
||||
priv->stage = clutter_actor_get_stage (actor);
|
||||
|
||||
click_action_set_pressed (click_action, TRUE);
|
||||
click_action_set_held (click_action, TRUE);
|
||||
click_action_query_long_press (click_action);
|
||||
break;
|
||||
|
||||
case CLUTTER_ENTER:
|
||||
click_action_set_pressed (click_action, priv->is_held);
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
case CLUTTER_LEAVE:
|
||||
click_action_set_pressed (click_action, FALSE);
|
||||
click_action_cancel_long_press (click_action);
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
case CLUTTER_TOUCH_CANCEL:
|
||||
clutter_click_action_release (click_action);
|
||||
break;
|
||||
|
||||
case CLUTTER_TOUCH_END:
|
||||
has_button = FALSE;
|
||||
|
||||
G_GNUC_FALLTHROUGH;
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
if (!priv->is_held)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if ((has_button && clutter_event_get_button (event) != priv->press_button) ||
|
||||
clutter_event_get_device (event) != priv->press_device ||
|
||||
clutter_event_get_event_sequence (event) != priv->press_sequence)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
click_action_set_held (click_action, FALSE);
|
||||
click_action_cancel_long_press (click_action);
|
||||
|
||||
g_clear_handle_id (&priv->long_press_id, g_source_remove);
|
||||
|
||||
target = clutter_stage_get_device_actor (CLUTTER_STAGE (clutter_actor_get_stage (actor)),
|
||||
clutter_event_get_device (event),
|
||||
clutter_event_get_event_sequence (event));
|
||||
|
||||
if (!clutter_actor_contains (actor, target))
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
/* exclude any button-mask so that we can compare
|
||||
* the press and release states properly */
|
||||
modifier_state = clutter_event_get_state (event) &
|
||||
~(CLUTTER_BUTTON1_MASK |
|
||||
CLUTTER_BUTTON2_MASK |
|
||||
CLUTTER_BUTTON3_MASK |
|
||||
CLUTTER_BUTTON4_MASK |
|
||||
CLUTTER_BUTTON5_MASK);
|
||||
|
||||
/* if press and release states don't match we
|
||||
* simply ignore modifier keys. i.e. modifier keys
|
||||
* are expected to be pressed throughout the whole
|
||||
* click */
|
||||
if (modifier_state != priv->modifier_state)
|
||||
priv->modifier_state = 0;
|
||||
|
||||
click_action_set_pressed (click_action, FALSE);
|
||||
|
||||
if (event_within_drag_threshold (click_action, event))
|
||||
g_signal_emit (click_action, click_signals[CLICKED], 0, actor);
|
||||
break;
|
||||
|
||||
case CLUTTER_MOTION:
|
||||
case CLUTTER_TOUCH_UPDATE:
|
||||
{
|
||||
if (clutter_event_get_device (event) != priv->press_device ||
|
||||
clutter_event_get_event_sequence (event) != priv->press_sequence)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if (!priv->is_held)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if (!event_within_drag_threshold (click_action, event))
|
||||
clutter_click_action_release (click_action);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return priv->is_held ? CLUTTER_EVENT_STOP : CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_click_action_sequence_cancelled (ClutterAction *action,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence)
|
||||
{
|
||||
ClutterClickAction *self = CLUTTER_CLICK_ACTION (action);
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (self);
|
||||
|
||||
if (priv->press_device == device && priv->press_sequence == sequence)
|
||||
clutter_click_action_release (self);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_click_action_set_actor (ClutterActorMeta *meta,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterClickAction *action = CLUTTER_CLICK_ACTION (meta);
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
|
||||
g_clear_handle_id (&priv->long_press_id, g_source_remove);
|
||||
|
||||
click_action_set_pressed (action, FALSE);
|
||||
click_action_set_held (action, FALSE);
|
||||
|
||||
CLUTTER_ACTOR_META_CLASS (clutter_click_action_parent_class)->set_actor (meta, actor);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_click_action_set_enabled (ClutterActorMeta *meta,
|
||||
gboolean is_enabled)
|
||||
{
|
||||
ClutterClickAction *click_action = CLUTTER_CLICK_ACTION (meta);
|
||||
ClutterActorMetaClass *parent_class =
|
||||
CLUTTER_ACTOR_META_CLASS (clutter_click_action_parent_class);
|
||||
|
||||
if (!is_enabled)
|
||||
clutter_click_action_release (click_action);
|
||||
|
||||
parent_class->set_enabled (meta, is_enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_click_action_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_LONG_PRESS_DURATION:
|
||||
priv->long_press_duration = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case PROP_LONG_PRESS_THRESHOLD:
|
||||
priv->long_press_threshold = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_click_action_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_HELD:
|
||||
g_value_set_boolean (value, priv->is_held);
|
||||
break;
|
||||
|
||||
case PROP_PRESSED:
|
||||
g_value_set_boolean (value, priv->is_pressed);
|
||||
break;
|
||||
|
||||
case PROP_LONG_PRESS_DURATION:
|
||||
g_value_set_int (value, priv->long_press_duration);
|
||||
break;
|
||||
|
||||
case PROP_LONG_PRESS_THRESHOLD:
|
||||
g_value_set_int (value, priv->long_press_threshold);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_click_action_dispose (GObject *gobject)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
|
||||
|
||||
g_clear_handle_id (&priv->long_press_id, g_source_remove);
|
||||
|
||||
G_OBJECT_CLASS (clutter_click_action_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_click_action_class_init (ClutterClickActionClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
|
||||
ClutterActionClass *action_class = CLUTTER_ACTION_CLASS (klass);
|
||||
|
||||
action_class->handle_event = clutter_click_action_handle_event;
|
||||
action_class->sequence_cancelled = clutter_click_action_sequence_cancelled;
|
||||
|
||||
meta_class->set_actor = clutter_click_action_set_actor;
|
||||
meta_class->set_enabled = clutter_click_action_set_enabled;
|
||||
|
||||
gobject_class->dispose = clutter_click_action_dispose;
|
||||
gobject_class->set_property = clutter_click_action_set_property;
|
||||
gobject_class->get_property = clutter_click_action_get_property;
|
||||
|
||||
/**
|
||||
* ClutterClickAction:pressed:
|
||||
*
|
||||
* Whether the clickable actor should be in "pressed" state
|
||||
*/
|
||||
obj_props[PROP_PRESSED] =
|
||||
g_param_spec_boolean ("pressed", NULL, NULL,
|
||||
FALSE,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterClickAction:held:
|
||||
*
|
||||
* Whether the clickable actor has the pointer grabbed
|
||||
*/
|
||||
obj_props[PROP_HELD] =
|
||||
g_param_spec_boolean ("held", NULL, NULL,
|
||||
FALSE,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterClickAction:long-press-duration:
|
||||
*
|
||||
* The minimum duration of a press for it to be recognized as a long
|
||||
* press gesture, in milliseconds.
|
||||
*
|
||||
* A value of -1 will make the #ClutterClickAction use the value of
|
||||
* the [property@Settings:long-press-duration] property.
|
||||
*/
|
||||
obj_props[PROP_LONG_PRESS_DURATION] =
|
||||
g_param_spec_int ("long-press-duration", NULL, NULL,
|
||||
-1, G_MAXINT,
|
||||
-1,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterClickAction:long-press-threshold:
|
||||
*
|
||||
* The maximum allowed distance that can be covered (on both axes) before
|
||||
* a long press gesture is cancelled, in pixels.
|
||||
*
|
||||
* A value of -1 will make the #ClutterClickAction use the value of
|
||||
* the [property@Settings:dnd-drag-threshold] property.
|
||||
*/
|
||||
obj_props[PROP_LONG_PRESS_THRESHOLD] =
|
||||
g_param_spec_int ("long-press-threshold", NULL, NULL,
|
||||
-1, G_MAXINT,
|
||||
-1,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class,
|
||||
PROP_LAST,
|
||||
obj_props);
|
||||
|
||||
/**
|
||||
* ClutterClickAction::clicked:
|
||||
* @action: the #ClutterClickAction that emitted the signal
|
||||
* @actor: the #ClutterActor attached to the @action
|
||||
*
|
||||
* The signal is emitted when the [class@Actor] to which
|
||||
* a #ClutterClickAction has been applied should respond to a
|
||||
* pointer button press and release events
|
||||
*/
|
||||
click_signals[CLICKED] =
|
||||
g_signal_new (I_("clicked"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterClickActionClass, clicked),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
|
||||
/**
|
||||
* ClutterClickAction::long-press:
|
||||
* @action: the #ClutterClickAction that emitted the signal
|
||||
* @actor: the #ClutterActor attached to the @action
|
||||
* @state: the long press state
|
||||
*
|
||||
* The signal is emitted during the long press gesture
|
||||
* handling.
|
||||
*
|
||||
* This signal can be emitted multiple times with different states.
|
||||
*
|
||||
* The %CLUTTER_LONG_PRESS_QUERY state will be emitted on button presses,
|
||||
* and its return value will determine whether the long press handling
|
||||
* should be initiated. If the signal handlers will return %TRUE, the
|
||||
* %CLUTTER_LONG_PRESS_QUERY state will be followed either by a signal
|
||||
* emission with the %CLUTTER_LONG_PRESS_ACTIVATE state if the long press
|
||||
* constraints were respected, or by a signal emission with the
|
||||
* %CLUTTER_LONG_PRESS_CANCEL state if the long press was cancelled.
|
||||
*
|
||||
* It is possible to forcibly cancel a long press detection using
|
||||
* [method@ClickAction.release].
|
||||
*
|
||||
* Return value: Only the %CLUTTER_LONG_PRESS_QUERY state uses the
|
||||
* returned value of the handler; other states will ignore it
|
||||
*/
|
||||
click_signals[LONG_PRESS] =
|
||||
g_signal_new (I_("long-press"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterClickActionClass, long_press),
|
||||
NULL, NULL,
|
||||
_clutter_marshal_BOOLEAN__OBJECT_ENUM,
|
||||
G_TYPE_BOOLEAN, 2,
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
CLUTTER_TYPE_LONG_PRESS_STATE);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_click_action_init (ClutterClickAction *self)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (self);
|
||||
|
||||
priv->long_press_threshold = -1;
|
||||
priv->long_press_duration = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_click_action_new:
|
||||
*
|
||||
* Creates a new #ClutterClickAction instance
|
||||
*
|
||||
* Return value: the newly created #ClutterClickAction
|
||||
*/
|
||||
ClutterAction *
|
||||
clutter_click_action_new (void)
|
||||
{
|
||||
return g_object_new (CLUTTER_TYPE_CLICK_ACTION, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_click_action_release:
|
||||
* @action: a #ClutterClickAction
|
||||
*
|
||||
* Emulates a release of the pointer button, which ungrabs the pointer
|
||||
* and unsets the [property@ClickAction:pressed] state.
|
||||
*
|
||||
* This function will also cancel the long press gesture if one was
|
||||
* initiated.
|
||||
*
|
||||
* This function is useful to break a grab, for instance after a certain
|
||||
* amount of time has passed.
|
||||
*/
|
||||
void
|
||||
clutter_click_action_release (ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickActionPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_CLICK_ACTION (action));
|
||||
|
||||
priv = clutter_click_action_get_instance_private (action);
|
||||
|
||||
if (!priv->is_held)
|
||||
return;
|
||||
|
||||
click_action_cancel_long_press (action);
|
||||
click_action_set_held (action, FALSE);
|
||||
click_action_set_pressed (action, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_click_action_get_button:
|
||||
* @action: a #ClutterClickAction
|
||||
*
|
||||
* Retrieves the button that was pressed.
|
||||
*
|
||||
* Return value: the button value
|
||||
*/
|
||||
guint
|
||||
clutter_click_action_get_button (ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickActionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0);
|
||||
|
||||
priv = clutter_click_action_get_instance_private (action);
|
||||
|
||||
return priv->press_button;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_click_action_get_state:
|
||||
* @action: a #ClutterClickAction
|
||||
*
|
||||
* Retrieves the modifier state of the click action.
|
||||
*
|
||||
* Return value: the modifier state parameter, or 0
|
||||
*/
|
||||
ClutterModifierType
|
||||
clutter_click_action_get_state (ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickActionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0);
|
||||
|
||||
priv = clutter_click_action_get_instance_private (action);
|
||||
|
||||
return priv->modifier_state;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_click_action_get_coords:
|
||||
* @action: a #ClutterClickAction
|
||||
* @press_x: (out): return location for the X coordinate, or %NULL
|
||||
* @press_y: (out): return location for the Y coordinate, or %NULL
|
||||
*
|
||||
* Retrieves the screen coordinates of the button press.
|
||||
*/
|
||||
void
|
||||
clutter_click_action_get_coords (ClutterClickAction *action,
|
||||
gfloat *press_x,
|
||||
gfloat *press_y)
|
||||
{
|
||||
ClutterClickActionPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTION (action));
|
||||
|
||||
priv = clutter_click_action_get_instance_private (action);
|
||||
|
||||
if (press_x != NULL)
|
||||
*press_x = priv->press_x;
|
||||
|
||||
if (press_y != NULL)
|
||||
*press_y = priv->press_y;
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*
|
||||
* Inspired by the StClickable class in GNOME Shell, written by:
|
||||
* Colin Walters <walters@verbum.org>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-action.h"
|
||||
#include "clutter/clutter-event.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_CLICK_ACTION (clutter_click_action_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterClickAction, clutter_click_action,
|
||||
CLUTTER, CLICK_ACTION, ClutterAction);
|
||||
|
||||
typedef struct _ClutterClickActionPrivate ClutterClickActionPrivate;
|
||||
|
||||
/**
|
||||
* ClutterClickActionClass:
|
||||
* @clicked: class handler for the #ClutterClickAction::clicked signal
|
||||
* @long_press: class handler for the #ClutterClickAction::long-press signal
|
||||
*
|
||||
* The #ClutterClickActionClass structure
|
||||
* contains only private data
|
||||
*/
|
||||
struct _ClutterClickActionClass
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterActionClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
void (* clicked) (ClutterClickAction *action,
|
||||
ClutterActor *actor);
|
||||
|
||||
gboolean (* long_press) (ClutterClickAction *action,
|
||||
ClutterActor *actor,
|
||||
ClutterLongPressState state);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterAction * clutter_click_action_new (void);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
guint clutter_click_action_get_button (ClutterClickAction *action);
|
||||
CLUTTER_EXPORT
|
||||
ClutterModifierType clutter_click_action_get_state (ClutterClickAction *action);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_click_action_get_coords (ClutterClickAction *action,
|
||||
gfloat *press_x,
|
||||
gfloat *press_y);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_click_action_release (ClutterClickAction *action);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,468 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2008 Intel Corporation.
|
||||
*
|
||||
* Authored By: Robert Bragg <robert@linux.intel.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterClone:
|
||||
*
|
||||
* An actor that displays a clone of a source actor
|
||||
*
|
||||
* #ClutterClone is a [class@Clutter.Actor] which draws with the paint
|
||||
* function of another actor, scaled to fit its own allocation.
|
||||
*
|
||||
* #ClutterClone can be used to efficiently clone any other actor.
|
||||
*
|
||||
* #ClutterClone does not require the presence of support for FBOs
|
||||
* in the underlying GL or GLES implementation.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-actor-private.h"
|
||||
#include "clutter/clutter-clone.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-main.h"
|
||||
#include "clutter/clutter-paint-volume-private.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
|
||||
typedef struct _ClutterClonePrivate
|
||||
{
|
||||
ClutterActor *clone_source;
|
||||
float x_scale, y_scale;
|
||||
|
||||
gulong source_destroy_id;
|
||||
} ClutterClonePrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterClone, clutter_clone, CLUTTER_TYPE_ACTOR)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_SOURCE,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
static void clutter_clone_set_source_internal (ClutterClone *clone,
|
||||
ClutterActor *source);
|
||||
static void
|
||||
clutter_clone_get_preferred_width (ClutterActor *self,
|
||||
gfloat for_height,
|
||||
gfloat *min_width_p,
|
||||
gfloat *natural_width_p)
|
||||
{
|
||||
ClutterClonePrivate *priv =
|
||||
clutter_clone_get_instance_private (CLUTTER_CLONE (self));
|
||||
ClutterActor *clone_source = priv->clone_source;
|
||||
|
||||
if (clone_source == NULL)
|
||||
{
|
||||
if (min_width_p)
|
||||
*min_width_p = 0;
|
||||
|
||||
if (natural_width_p)
|
||||
*natural_width_p = 0;
|
||||
}
|
||||
else
|
||||
clutter_actor_get_preferred_width (clone_source,
|
||||
for_height,
|
||||
min_width_p,
|
||||
natural_width_p);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_clone_get_preferred_height (ClutterActor *self,
|
||||
gfloat for_width,
|
||||
gfloat *min_height_p,
|
||||
gfloat *natural_height_p)
|
||||
{
|
||||
ClutterClonePrivate *priv =
|
||||
clutter_clone_get_instance_private (CLUTTER_CLONE (self));
|
||||
ClutterActor *clone_source = priv->clone_source;
|
||||
|
||||
if (clone_source == NULL)
|
||||
{
|
||||
if (min_height_p)
|
||||
*min_height_p = 0;
|
||||
|
||||
if (natural_height_p)
|
||||
*natural_height_p = 0;
|
||||
}
|
||||
else
|
||||
clutter_actor_get_preferred_height (clone_source,
|
||||
for_width,
|
||||
min_height_p,
|
||||
natural_height_p);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_clone_paint (ClutterActor *actor,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
ClutterClone *self = CLUTTER_CLONE (actor);
|
||||
ClutterClonePrivate *priv = clutter_clone_get_instance_private (self);
|
||||
gboolean was_unmapped = FALSE;
|
||||
|
||||
if (priv->clone_source == NULL)
|
||||
return;
|
||||
|
||||
CLUTTER_NOTE (PAINT, "painting clone actor '%s'",
|
||||
_clutter_actor_get_debug_name (actor));
|
||||
|
||||
/* The final bits of magic:
|
||||
* - We need to override the paint opacity of the actor with our own
|
||||
* opacity.
|
||||
* - We need to inform the actor that it's in a clone paint (for the function
|
||||
* clutter_actor_is_in_clone_paint())
|
||||
* - We need to stop clutter_actor_paint applying the model view matrix of
|
||||
* the clone source actor.
|
||||
*/
|
||||
_clutter_actor_set_in_clone_paint (priv->clone_source, TRUE);
|
||||
clutter_actor_set_opacity_override (priv->clone_source,
|
||||
clutter_actor_get_paint_opacity (actor));
|
||||
_clutter_actor_set_enable_model_view_transform (priv->clone_source, FALSE);
|
||||
|
||||
if (!clutter_actor_is_mapped (priv->clone_source))
|
||||
{
|
||||
_clutter_actor_set_enable_paint_unmapped (priv->clone_source, TRUE);
|
||||
was_unmapped = TRUE;
|
||||
}
|
||||
|
||||
/* If the source isn't ultimately parented to a toplevel, it can't be
|
||||
* realized or painted.
|
||||
*/
|
||||
if (clutter_actor_is_realized (priv->clone_source))
|
||||
{
|
||||
CoglFramebuffer *fb = NULL;
|
||||
|
||||
if (priv->x_scale != 1.0 || priv->y_scale != 1.0)
|
||||
{
|
||||
fb = clutter_paint_context_get_framebuffer (paint_context);
|
||||
|
||||
cogl_framebuffer_push_matrix (fb);
|
||||
cogl_framebuffer_scale (fb, priv->x_scale, priv->y_scale, 1.0f);
|
||||
}
|
||||
|
||||
_clutter_actor_push_clone_paint ();
|
||||
clutter_actor_paint (priv->clone_source, paint_context);
|
||||
_clutter_actor_pop_clone_paint ();
|
||||
|
||||
if (fb != NULL)
|
||||
cogl_framebuffer_pop_matrix (fb);
|
||||
}
|
||||
|
||||
if (was_unmapped)
|
||||
_clutter_actor_set_enable_paint_unmapped (priv->clone_source, FALSE);
|
||||
|
||||
_clutter_actor_set_enable_model_view_transform (priv->clone_source, TRUE);
|
||||
clutter_actor_set_opacity_override (priv->clone_source, -1);
|
||||
_clutter_actor_set_in_clone_paint (priv->clone_source, FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_clone_get_paint_volume (ClutterActor *actor,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
ClutterClonePrivate *priv =
|
||||
clutter_clone_get_instance_private (CLUTTER_CLONE (actor));
|
||||
const ClutterPaintVolume *source_volume;
|
||||
|
||||
/* if the source is not set the paint volume is defined to be empty */
|
||||
if (priv->clone_source == NULL)
|
||||
return TRUE;
|
||||
|
||||
/* query the volume of the source actor and simply masquerade it as
|
||||
* the clones volume... */
|
||||
source_volume = clutter_actor_get_paint_volume (priv->clone_source);
|
||||
if (source_volume == NULL)
|
||||
return FALSE;
|
||||
|
||||
clutter_paint_volume_init_from_paint_volume (volume, source_volume);
|
||||
_clutter_paint_volume_set_reference_actor (volume, actor);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_clone_has_overlaps (ClutterActor *actor)
|
||||
{
|
||||
ClutterClonePrivate *priv =
|
||||
clutter_clone_get_instance_private (CLUTTER_CLONE (actor));
|
||||
|
||||
/* The clone has overlaps iff the source has overlaps */
|
||||
|
||||
if (priv->clone_source == NULL)
|
||||
return FALSE;
|
||||
|
||||
return clutter_actor_has_overlaps (priv->clone_source);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_clone_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box)
|
||||
{
|
||||
ClutterClonePrivate *priv =
|
||||
clutter_clone_get_instance_private (CLUTTER_CLONE (self));
|
||||
ClutterActorClass *parent_class;
|
||||
ClutterActorBox source_box;
|
||||
float x_scale, y_scale;
|
||||
|
||||
/* chain up */
|
||||
parent_class = CLUTTER_ACTOR_CLASS (clutter_clone_parent_class);
|
||||
parent_class->allocate (self, box);
|
||||
|
||||
if (priv->clone_source == NULL)
|
||||
return;
|
||||
|
||||
/* ClutterActor delays allocating until the actor is shown; however
|
||||
* we cannot paint it correctly in that case, so force an allocation.
|
||||
*/
|
||||
if (clutter_actor_get_parent (priv->clone_source) != NULL &&
|
||||
!clutter_actor_has_allocation (priv->clone_source))
|
||||
{
|
||||
float x = 0.f;
|
||||
float y = 0.f;
|
||||
|
||||
clutter_actor_get_fixed_position (priv->clone_source, &x, &y);
|
||||
clutter_actor_allocate_preferred_size (priv->clone_source, x, y);
|
||||
}
|
||||
|
||||
clutter_actor_get_allocation_box (priv->clone_source, &source_box);
|
||||
|
||||
/* We need to scale what the clone-source actor paints to fill our own
|
||||
* allocation...
|
||||
*/
|
||||
x_scale = clutter_actor_box_get_width (box)
|
||||
/ clutter_actor_box_get_width (&source_box);
|
||||
y_scale = clutter_actor_box_get_height (box)
|
||||
/ clutter_actor_box_get_height (&source_box);
|
||||
|
||||
if (!G_APPROX_VALUE (priv->x_scale, x_scale, FLT_EPSILON) ||
|
||||
!G_APPROX_VALUE (priv->y_scale, y_scale, FLT_EPSILON))
|
||||
{
|
||||
priv->x_scale = x_scale;
|
||||
priv->y_scale = y_scale;
|
||||
clutter_actor_queue_redraw (self);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* XXX - this is wrong: ClutterClone cannot clone unparented
|
||||
* actors, as it will break all invariants
|
||||
*/
|
||||
|
||||
/* we act like a "foster parent" for the source we are cloning;
|
||||
* if the source has not been parented we have to force an
|
||||
* allocation on it, so that we can paint it correctly from
|
||||
* within our paint() implementation. since the actor does not
|
||||
* have a parent, and thus it won't be painted by the usual
|
||||
* paint cycle, we can safely give it as much size as it requires
|
||||
*/
|
||||
if (clutter_actor_get_parent (priv->clone_source) == NULL)
|
||||
clutter_actor_allocate_preferred_size (priv->clone_source);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_clone_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterClone *self = CLUTTER_CLONE (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SOURCE:
|
||||
clutter_clone_set_source (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_clone_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterClonePrivate *priv =
|
||||
clutter_clone_get_instance_private (CLUTTER_CLONE (gobject));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SOURCE:
|
||||
g_value_set_object (value, priv->clone_source);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_clone_dispose (GObject *gobject)
|
||||
{
|
||||
clutter_clone_set_source_internal (CLUTTER_CLONE (gobject), NULL);
|
||||
|
||||
G_OBJECT_CLASS (clutter_clone_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_clone_class_init (ClutterCloneClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
actor_class->paint = clutter_clone_paint;
|
||||
actor_class->get_paint_volume = clutter_clone_get_paint_volume;
|
||||
actor_class->get_preferred_width = clutter_clone_get_preferred_width;
|
||||
actor_class->get_preferred_height = clutter_clone_get_preferred_height;
|
||||
actor_class->allocate = clutter_clone_allocate;
|
||||
actor_class->has_overlaps = clutter_clone_has_overlaps;
|
||||
|
||||
gobject_class->dispose = clutter_clone_dispose;
|
||||
gobject_class->set_property = clutter_clone_set_property;
|
||||
gobject_class->get_property = clutter_clone_get_property;
|
||||
|
||||
/**
|
||||
* ClutterClone:source:
|
||||
*
|
||||
* This property specifies the source actor being cloned.
|
||||
*/
|
||||
obj_props[PROP_SOURCE] =
|
||||
g_param_spec_object ("source", NULL, NULL,
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_clone_init (ClutterClone *self)
|
||||
{
|
||||
ClutterClonePrivate *priv = clutter_clone_get_instance_private (self);
|
||||
|
||||
priv->x_scale = 1.f;
|
||||
priv->y_scale = 1.f;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_clone_new:
|
||||
* @source: a #ClutterActor, or %NULL
|
||||
*
|
||||
* Creates a new #ClutterActor which clones @source/
|
||||
*
|
||||
* Return value: the newly created #ClutterClone
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_clone_new (ClutterActor *source)
|
||||
{
|
||||
return g_object_new (CLUTTER_TYPE_CLONE,
|
||||
"source", source,
|
||||
"accessible-role", ATK_ROLE_IMAGE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
on_source_destroyed (ClutterActor *source,
|
||||
ClutterClone *self)
|
||||
{
|
||||
clutter_clone_set_source_internal (self, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_clone_set_source_internal (ClutterClone *self,
|
||||
ClutterActor *source)
|
||||
{
|
||||
ClutterClonePrivate *priv = clutter_clone_get_instance_private (self);
|
||||
|
||||
if (priv->clone_source == source)
|
||||
return;
|
||||
|
||||
if (priv->clone_source != NULL)
|
||||
{
|
||||
g_clear_signal_handler (&priv->source_destroy_id, priv->clone_source);
|
||||
_clutter_actor_detach_clone (priv->clone_source, CLUTTER_ACTOR (self));
|
||||
g_object_unref (priv->clone_source);
|
||||
priv->clone_source = NULL;
|
||||
}
|
||||
|
||||
if (source != NULL)
|
||||
{
|
||||
priv->clone_source = g_object_ref (source);
|
||||
_clutter_actor_attach_clone (priv->clone_source, CLUTTER_ACTOR (self));
|
||||
priv->source_destroy_id = g_signal_connect (priv->clone_source, "destroy",
|
||||
G_CALLBACK (on_source_destroyed), self);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SOURCE]);
|
||||
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_clone_set_source:
|
||||
* @self: a #ClutterClone
|
||||
* @source: (allow-none): a #ClutterActor, or %NULL
|
||||
*
|
||||
* Sets @source as the source actor to be cloned by @self.
|
||||
*/
|
||||
void
|
||||
clutter_clone_set_source (ClutterClone *self,
|
||||
ClutterActor *source)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_CLONE (self));
|
||||
g_return_if_fail (source == NULL || CLUTTER_IS_ACTOR (source));
|
||||
|
||||
clutter_clone_set_source_internal (self, source);
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_clone_get_source:
|
||||
* @self: a #ClutterClone
|
||||
*
|
||||
* Retrieves the source #ClutterActor being cloned by @self.
|
||||
*
|
||||
* Return value: (transfer none): the actor source for the clone
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_clone_get_source (ClutterClone *self)
|
||||
{
|
||||
ClutterClonePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_CLONE (self), NULL);
|
||||
|
||||
priv = clutter_clone_get_instance_private (self);
|
||||
return priv->clone_source;
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2008 Intel Corporation.
|
||||
*
|
||||
* Authored By: Robert Bragg <robert@linux.intel.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-actor.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_CLONE (clutter_clone_get_type ())
|
||||
|
||||
/**
|
||||
* ClutterCloneClass:
|
||||
*
|
||||
* The #ClutterCloneClass structure contains only private data
|
||||
*/
|
||||
struct _ClutterCloneClass
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterActorClass parent_class;
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterClone,
|
||||
clutter_clone,
|
||||
CLUTTER, CLONE,
|
||||
ClutterActor)
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_clone_new (ClutterActor *source);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_clone_set_source (ClutterClone *self,
|
||||
ClutterActor *source);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_clone_get_source (ClutterClone *self);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2024 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "clutter/clutter-color-manager.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
unsigned int clutter_color_manager_get_next_id (ClutterColorManager *color_manager);
|
||||
|
||||
CoglSnippet * clutter_color_manager_lookup_snippet (ClutterColorManager *color_manager,
|
||||
const ClutterColorTransformKey *key);
|
||||
|
||||
void clutter_color_manager_add_snippet (ClutterColorManager *color_manager,
|
||||
const ClutterColorTransformKey *key,
|
||||
CoglSnippet *snippet);
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2024 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-color-manager-private.h"
|
||||
|
||||
#include "clutter/clutter-color-state-params.h"
|
||||
#include "clutter/clutter-color-state-private.h"
|
||||
#include "clutter/clutter-context.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_CONTEXT,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[N_PROPS];
|
||||
|
||||
struct _ClutterColorManager
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
ClutterContext *context;
|
||||
|
||||
GHashTable *snippet_cache;
|
||||
unsigned int id_counter;
|
||||
ClutterColorState *default_color_state;
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE (ClutterColorManager, clutter_color_manager, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
clutter_color_manager_finalize (GObject *object)
|
||||
{
|
||||
ClutterColorManager *color_manager = CLUTTER_COLOR_MANAGER (object);
|
||||
|
||||
g_clear_object (&color_manager->default_color_state);
|
||||
|
||||
g_clear_pointer (&color_manager->snippet_cache, g_hash_table_unref);
|
||||
|
||||
G_OBJECT_CLASS (clutter_color_manager_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_manager_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterColorManager *color_manager = CLUTTER_COLOR_MANAGER (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTEXT:
|
||||
color_manager->context = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_manager_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterColorManager *color_manager = CLUTTER_COLOR_MANAGER (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTEXT:
|
||||
g_value_set_object (value, color_manager->context);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_manager_class_init (ClutterColorManagerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = clutter_color_manager_finalize;
|
||||
object_class->set_property = clutter_color_manager_set_property;
|
||||
object_class->get_property = clutter_color_manager_get_property;
|
||||
|
||||
/**
|
||||
* ClutterColorManager:context:
|
||||
*
|
||||
* The associated ClutterContext.
|
||||
*/
|
||||
obj_props[PROP_CONTEXT] =
|
||||
g_param_spec_object ("context", NULL, NULL,
|
||||
CLUTTER_TYPE_CONTEXT,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_manager_init (ClutterColorManager *color_manager)
|
||||
{
|
||||
color_manager->snippet_cache =
|
||||
g_hash_table_new_full (clutter_color_transform_key_hash,
|
||||
clutter_color_transform_key_equal,
|
||||
g_free,
|
||||
g_object_unref);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
clutter_color_manager_get_next_id (ClutterColorManager *color_manager)
|
||||
{
|
||||
return ++color_manager->id_counter;
|
||||
}
|
||||
|
||||
ClutterColorState *
|
||||
clutter_color_manager_get_default_color_state (ClutterColorManager *color_manager)
|
||||
{
|
||||
if (!color_manager->default_color_state)
|
||||
{
|
||||
color_manager->default_color_state =
|
||||
clutter_color_state_params_new (color_manager->context,
|
||||
CLUTTER_COLORSPACE_SRGB,
|
||||
CLUTTER_TRANSFER_FUNCTION_SRGB);
|
||||
}
|
||||
|
||||
return color_manager->default_color_state;
|
||||
}
|
||||
|
||||
CoglSnippet *
|
||||
clutter_color_manager_lookup_snippet (ClutterColorManager *color_manager,
|
||||
const ClutterColorTransformKey *key)
|
||||
{
|
||||
return g_hash_table_lookup (color_manager->snippet_cache, key);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_color_manager_add_snippet (ClutterColorManager *color_manager,
|
||||
const ClutterColorTransformKey *key,
|
||||
CoglSnippet *snippet)
|
||||
{
|
||||
g_hash_table_insert (color_manager->snippet_cache,
|
||||
g_memdup2 (key, sizeof (*key)),
|
||||
g_object_ref (snippet));
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2024 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
|
||||
#define CLUTTER_TYPE_COLOR_MANAGER (clutter_color_manager_get_type ())
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_FINAL_TYPE (ClutterColorManager, clutter_color_manager,
|
||||
CLUTTER, COLOR_MANAGER, GObject)
|
||||
|
||||
/**
|
||||
* clutter_color_manager_get_default_color_state: (skip)
|
||||
*/
|
||||
CLUTTER_EXPORT
|
||||
ClutterColorState * clutter_color_manager_get_default_color_state (ClutterColorManager *color_manager);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-color-state.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_COLORSPACE_SRGB,
|
||||
CLUTTER_COLORSPACE_BT2020,
|
||||
CLUTTER_COLORSPACE_NTSC,
|
||||
} ClutterColorspace;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_TRANSFER_FUNCTION_SRGB,
|
||||
CLUTTER_TRANSFER_FUNCTION_PQ,
|
||||
CLUTTER_TRANSFER_FUNCTION_BT709,
|
||||
CLUTTER_TRANSFER_FUNCTION_LINEAR,
|
||||
} ClutterTransferFunction;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_COLORIMETRY_TYPE_COLORSPACE,
|
||||
CLUTTER_COLORIMETRY_TYPE_PRIMARIES,
|
||||
} ClutterColorimetryType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_EOTF_TYPE_NAMED,
|
||||
CLUTTER_EOTF_TYPE_GAMMA,
|
||||
} ClutterEOTFType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_LUMINANCE_TYPE_DERIVED,
|
||||
CLUTTER_LUMINANCE_TYPE_EXPLICIT,
|
||||
} ClutterLuminanceType;
|
||||
|
||||
typedef struct _ClutterPrimaries
|
||||
{
|
||||
float r_x, r_y;
|
||||
float g_x, g_y;
|
||||
float b_x, b_y;
|
||||
float w_x, w_y;
|
||||
} ClutterPrimaries;
|
||||
|
||||
typedef struct _ClutterColorimetry
|
||||
{
|
||||
ClutterColorimetryType type : 1;
|
||||
union
|
||||
{
|
||||
ClutterColorspace colorspace;
|
||||
ClutterPrimaries *primaries;
|
||||
};
|
||||
} ClutterColorimetry;
|
||||
|
||||
typedef struct _ClutterEOTF
|
||||
{
|
||||
ClutterEOTFType type : 1;
|
||||
union
|
||||
{
|
||||
ClutterTransferFunction tf_name;
|
||||
float gamma_exp;
|
||||
};
|
||||
} ClutterEOTF;
|
||||
|
||||
typedef struct _ClutterLuminance
|
||||
{
|
||||
ClutterLuminanceType type : 1;
|
||||
float min;
|
||||
float max;
|
||||
float ref;
|
||||
} ClutterLuminance;
|
||||
|
||||
#define CLUTTER_TYPE_COLOR_STATE_PARAMS (clutter_color_state_params_get_type ())
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_FINAL_TYPE (ClutterColorStateParams, clutter_color_state_params,
|
||||
CLUTTER, COLOR_STATE_PARAMS,
|
||||
ClutterColorState)
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterColorState * clutter_color_state_params_new (ClutterContext *context,
|
||||
ClutterColorspace colorspace,
|
||||
ClutterTransferFunction transfer_function);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterColorState * clutter_color_state_params_new_full (ClutterContext *context,
|
||||
ClutterColorspace colorspace,
|
||||
ClutterTransferFunction transfer_function,
|
||||
ClutterPrimaries *primaries,
|
||||
float gamma_exp,
|
||||
float min_lum,
|
||||
float max_lum,
|
||||
float ref_lum);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterColorState * clutter_color_state_params_new_from_primitives (ClutterContext *context,
|
||||
ClutterColorimetry colorimetry,
|
||||
ClutterEOTF eotf,
|
||||
ClutterLuminance luminance);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
const ClutterColorimetry * clutter_color_state_params_get_colorimetry (ClutterColorStateParams *color_state_params);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
const ClutterEOTF * clutter_color_state_params_get_eotf (ClutterColorStateParams *color_state_params);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
const ClutterLuminance * clutter_color_state_params_get_luminance (ClutterColorStateParams *color_state_params);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
const ClutterLuminance * clutter_eotf_get_default_luminance (ClutterEOTF eotf);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
const ClutterPrimaries * clutter_colorspace_to_primaries (ClutterColorspace colorspace);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_primaries_ensure_normalized_range (ClutterPrimaries *primaries);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2024 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "clutter/clutter-color-state.h"
|
||||
|
||||
typedef struct _ClutterColorTransformKey
|
||||
{
|
||||
/* 3 bits to define TransferFunction enums
|
||||
* + 1 bit to define Gamma TF */
|
||||
guint source_eotf_bits : 4;
|
||||
guint target_eotf_bits : 4;
|
||||
/* When there is a luminance mapping snippet */
|
||||
guint luminance_bit : 1;
|
||||
/* When there is a color trans snippet */
|
||||
guint color_trans_bit : 1;
|
||||
} ClutterColorTransformKey;
|
||||
|
||||
void clutter_color_transform_key_init (ClutterColorTransformKey *key,
|
||||
ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state);
|
||||
|
||||
guint clutter_color_transform_key_hash (gconstpointer data);
|
||||
|
||||
gboolean clutter_color_transform_key_equal (gconstpointer data1,
|
||||
gconstpointer data2);
|
||||
@@ -1,383 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2022 Intel Corporation.
|
||||
* Copyright (C) 2023-2024 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Naveen Kumar <naveen1.kumar@intel.com>
|
||||
* Jonas Ådahl <jadahl@redhat.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterColorState:
|
||||
*
|
||||
* Color state of each ClutterActor
|
||||
*
|
||||
* The #ClutterColorState class contains the colorspace of each color
|
||||
* states (e.g. sRGB colorspace).
|
||||
*
|
||||
* Each [class@Actor] would own such an object.
|
||||
*
|
||||
* A single #ClutterColorState object can be shared by multiple [class@Actor]
|
||||
* or maybe a separate color state for each [class@Actor] (depending on whether
|
||||
* #ClutterColorState would be statefull or stateless).
|
||||
*
|
||||
* #ClutterColorState, if not set during construction, it will default to sRGB
|
||||
* color state
|
||||
*
|
||||
* The #ClutterColorState would have API to get the colorspace, whether the
|
||||
* actor content is in pq or not, and things like that
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-color-state-private.h"
|
||||
|
||||
#include "clutter/clutter-color-manager-private.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_CONTEXT,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[N_PROPS];
|
||||
|
||||
typedef struct _ClutterColorStatePrivate
|
||||
{
|
||||
ClutterContext *context;
|
||||
|
||||
unsigned int id;
|
||||
} ClutterColorStatePrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterColorState,
|
||||
clutter_color_state,
|
||||
G_TYPE_OBJECT)
|
||||
|
||||
guint
|
||||
clutter_color_transform_key_hash (gconstpointer data)
|
||||
{
|
||||
const ClutterColorTransformKey *key = data;
|
||||
|
||||
return key->source_eotf_bits << 0 &
|
||||
key->target_eotf_bits << 4 &
|
||||
key->luminance_bit << 8 &
|
||||
key->color_trans_bit << 9;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_color_transform_key_equal (gconstpointer data1,
|
||||
gconstpointer data2)
|
||||
{
|
||||
const ClutterColorTransformKey *key1 = data1;
|
||||
const ClutterColorTransformKey *key2 = data2;
|
||||
|
||||
return (key1->source_eotf_bits == key2->source_eotf_bits &&
|
||||
key1->target_eotf_bits == key2->target_eotf_bits &&
|
||||
key1->luminance_bit == key2->luminance_bit &&
|
||||
key1->color_trans_bit == key2->color_trans_bit);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_color_transform_key_init (ClutterColorTransformKey *key,
|
||||
ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state)
|
||||
{
|
||||
ClutterColorStateClass *color_state_class =
|
||||
CLUTTER_COLOR_STATE_GET_CLASS (color_state);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_COLOR_STATE (color_state));
|
||||
g_return_if_fail (CLUTTER_IS_COLOR_STATE (target_color_state));
|
||||
|
||||
color_state_class->init_color_transform_key (color_state,
|
||||
target_color_state,
|
||||
key);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
clutter_color_state_get_id (ClutterColorState *color_state)
|
||||
{
|
||||
ClutterColorStatePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_COLOR_STATE (color_state), 0);
|
||||
|
||||
priv = clutter_color_state_get_instance_private (color_state);
|
||||
|
||||
return priv->id;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_state_constructed (GObject *object)
|
||||
{
|
||||
ClutterColorState *color_state = CLUTTER_COLOR_STATE (object);
|
||||
ClutterColorStatePrivate *priv =
|
||||
clutter_color_state_get_instance_private (color_state);
|
||||
ClutterColorManager *color_manager;
|
||||
|
||||
g_warn_if_fail (priv->context);
|
||||
|
||||
color_manager = clutter_context_get_color_manager (priv->context);
|
||||
|
||||
priv->id = clutter_color_manager_get_next_id (color_manager);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_state_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterColorState *color_state = CLUTTER_COLOR_STATE (object);
|
||||
ClutterColorStatePrivate *priv;
|
||||
|
||||
priv = clutter_color_state_get_instance_private (color_state);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTEXT:
|
||||
priv->context = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_state_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterColorState *color_state = CLUTTER_COLOR_STATE (object);
|
||||
ClutterColorStatePrivate *priv =
|
||||
clutter_color_state_get_instance_private (color_state);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTEXT:
|
||||
g_value_set_object (value, priv->context);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_state_class_init (ClutterColorStateClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = clutter_color_state_constructed;
|
||||
object_class->set_property = clutter_color_state_set_property;
|
||||
object_class->get_property = clutter_color_state_get_property;
|
||||
|
||||
/**
|
||||
* ClutterColorState:context:
|
||||
*
|
||||
* The associated ClutterContext.
|
||||
*/
|
||||
obj_props[PROP_CONTEXT] = g_param_spec_object ("context", NULL, NULL,
|
||||
CLUTTER_TYPE_CONTEXT,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_state_init (ClutterColorState *color_state)
|
||||
{
|
||||
}
|
||||
|
||||
static CoglSnippet *
|
||||
clutter_color_state_create_transform_snippet (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state)
|
||||
{
|
||||
ClutterColorStateClass *color_state_class =
|
||||
CLUTTER_COLOR_STATE_GET_CLASS (color_state);
|
||||
|
||||
return color_state_class->create_transform_snippet (color_state,
|
||||
target_color_state);
|
||||
}
|
||||
|
||||
static CoglSnippet *
|
||||
clutter_color_state_get_transform_snippet (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state)
|
||||
{
|
||||
ClutterColorStatePrivate *priv;
|
||||
ClutterColorManager *color_manager;
|
||||
ClutterColorTransformKey transform_key;
|
||||
CoglSnippet *snippet;
|
||||
|
||||
priv = clutter_color_state_get_instance_private (color_state);
|
||||
color_manager = clutter_context_get_color_manager (priv->context);
|
||||
|
||||
clutter_color_transform_key_init (&transform_key,
|
||||
color_state,
|
||||
target_color_state);
|
||||
snippet = clutter_color_manager_lookup_snippet (color_manager,
|
||||
&transform_key);
|
||||
if (snippet)
|
||||
return g_object_ref (snippet);
|
||||
|
||||
snippet = clutter_color_state_create_transform_snippet (color_state,
|
||||
target_color_state);
|
||||
|
||||
clutter_color_manager_add_snippet (color_manager,
|
||||
&transform_key,
|
||||
g_object_ref (snippet));
|
||||
return snippet;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_color_state_update_uniforms (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
CoglPipeline *pipeline)
|
||||
{
|
||||
ClutterColorStateClass *color_state_class =
|
||||
CLUTTER_COLOR_STATE_GET_CLASS (color_state);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_COLOR_STATE (color_state));
|
||||
g_return_if_fail (CLUTTER_IS_COLOR_STATE (target_color_state));
|
||||
|
||||
color_state_class->update_uniforms (color_state,
|
||||
target_color_state,
|
||||
pipeline);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_color_state_do_transform (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
const float *input,
|
||||
float *output,
|
||||
int n_samples)
|
||||
{
|
||||
ClutterColorStateClass *color_state_class =
|
||||
CLUTTER_COLOR_STATE_GET_CLASS (color_state);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_COLOR_STATE (color_state));
|
||||
g_return_if_fail (CLUTTER_IS_COLOR_STATE (target_color_state));
|
||||
|
||||
color_state_class->do_transform (color_state,
|
||||
target_color_state,
|
||||
input,
|
||||
output,
|
||||
n_samples);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_color_state_add_pipeline_transform (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
CoglPipeline *pipeline)
|
||||
{
|
||||
g_autoptr (CoglSnippet) snippet = NULL;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_COLOR_STATE (color_state));
|
||||
g_return_if_fail (CLUTTER_IS_COLOR_STATE (target_color_state));
|
||||
|
||||
if (clutter_color_state_equals (color_state, target_color_state))
|
||||
return;
|
||||
|
||||
snippet = clutter_color_state_get_transform_snippet (color_state,
|
||||
target_color_state);
|
||||
cogl_pipeline_add_snippet (pipeline, snippet);
|
||||
|
||||
clutter_color_state_update_uniforms (color_state,
|
||||
target_color_state,
|
||||
pipeline);
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_color_state_equals (ClutterColorState *color_state,
|
||||
ClutterColorState *other_color_state)
|
||||
{
|
||||
ClutterColorStateClass *color_state_class =
|
||||
CLUTTER_COLOR_STATE_GET_CLASS (color_state);
|
||||
|
||||
if (color_state == other_color_state)
|
||||
return TRUE;
|
||||
|
||||
if (color_state == NULL || other_color_state == NULL)
|
||||
return FALSE;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_COLOR_STATE (color_state), FALSE);
|
||||
g_return_val_if_fail (CLUTTER_IS_COLOR_STATE (other_color_state), FALSE);
|
||||
|
||||
if (G_OBJECT_TYPE (color_state) != G_OBJECT_TYPE (other_color_state))
|
||||
return FALSE;
|
||||
|
||||
return color_state_class->equals (color_state, other_color_state);
|
||||
}
|
||||
|
||||
char *
|
||||
clutter_color_state_to_string (ClutterColorState *color_state)
|
||||
{
|
||||
ClutterColorStateClass *color_state_class =
|
||||
CLUTTER_COLOR_STATE_GET_CLASS (color_state);
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_COLOR_STATE (color_state), NULL);
|
||||
|
||||
return color_state_class->to_string (color_state);
|
||||
}
|
||||
|
||||
ClutterEncodingRequiredFormat
|
||||
clutter_color_state_required_format (ClutterColorState *color_state)
|
||||
{
|
||||
|
||||
ClutterColorStateClass *color_state_class =
|
||||
CLUTTER_COLOR_STATE_GET_CLASS (color_state);
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_COLOR_STATE (color_state), FALSE);
|
||||
|
||||
return color_state_class->required_format (color_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_color_state_get_blending:
|
||||
* @color_state: a #ClutterColorState
|
||||
* @force: if a linear variant should be forced
|
||||
*
|
||||
* Retrieves a variant of @color_state that is suitable for blending. This
|
||||
* usually is a variant with linear transfer characteristics. If @color_state
|
||||
* already is a #ClutterColorState suitable for blending, then @color_state is
|
||||
* returned.
|
||||
*
|
||||
* If @force is TRUE then linear transfer characteristics are used always.
|
||||
*
|
||||
* Returns: (transfer full): the #ClutterColorState suitable for blending
|
||||
*/
|
||||
ClutterColorState *
|
||||
clutter_color_state_get_blending (ClutterColorState *color_state,
|
||||
gboolean force)
|
||||
{
|
||||
ClutterColorStateClass *color_state_class =
|
||||
CLUTTER_COLOR_STATE_GET_CLASS (color_state);
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_COLOR_STATE (color_state), FALSE);
|
||||
|
||||
return color_state_class->get_blending (color_state, force);
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2022 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Naveen Kumar <naveen1.kumar@intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_COLOR_STATE (clutter_color_state_get_type ())
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterColorState,
|
||||
clutter_color_state,
|
||||
CLUTTER, COLOR_STATE,
|
||||
GObject)
|
||||
|
||||
struct _ClutterColorStateClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* init_color_transform_key) (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
ClutterColorTransformKey *key);
|
||||
|
||||
CoglSnippet * (* create_transform_snippet) (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state);
|
||||
|
||||
void (* update_uniforms) (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
CoglPipeline *pipeline);
|
||||
|
||||
void (* do_transform) (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
const float *input,
|
||||
float *output,
|
||||
int n_samples);
|
||||
|
||||
gboolean (* equals) (ClutterColorState *color_state,
|
||||
ClutterColorState *other_color_state);
|
||||
|
||||
char * (* to_string) (ClutterColorState *color_state);
|
||||
|
||||
ClutterEncodingRequiredFormat (* required_format) (ClutterColorState *color_state);
|
||||
|
||||
ClutterColorState * (* get_blending) (ClutterColorState *color_state,
|
||||
gboolean force);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
char * clutter_color_state_to_string (ClutterColorState *color_state);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
unsigned int clutter_color_state_get_id (ClutterColorState *color_state);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_color_state_add_pipeline_transform (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
CoglPipeline *pipeline);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_color_state_update_uniforms (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
CoglPipeline *pipeline);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_color_state_do_transform (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
const float *input,
|
||||
float *output,
|
||||
int n_samples);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_color_state_equals (ClutterColorState *color_state,
|
||||
ClutterColorState *other_color_state);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterEncodingRequiredFormat clutter_color_state_required_format (ClutterColorState *color_state);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterColorState * clutter_color_state_get_blending (ClutterColorState *color_state,
|
||||
gboolean force);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,299 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterColorizeEffect:
|
||||
*
|
||||
* A colorization effect
|
||||
*
|
||||
* #ClutterColorizeEffect is a sub-class of #ClutterEffect that
|
||||
* colorizes an actor with the given tint.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-colorize-effect.h"
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-enum-types.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
typedef struct _ClutterColorizeEffectPrivate
|
||||
{
|
||||
ClutterOffscreenEffect parent_instance;
|
||||
|
||||
/* the tint of the colorization */
|
||||
CoglColor tint;
|
||||
|
||||
gint tint_uniform;
|
||||
|
||||
CoglPipeline *pipeline;
|
||||
} ClutterColorizeEffectPrivate;
|
||||
|
||||
/* the magic gray vec3 has been taken from the NTSC conversion weights
|
||||
* as defined by:
|
||||
*
|
||||
* "OpenGL Superbible, 4th Edition"
|
||||
* -- Richard S. Wright Jr, Benjamin Lipchak, Nicholas Haemel
|
||||
* Addison-Wesley
|
||||
*/
|
||||
static const gchar *colorize_glsl_declarations =
|
||||
"uniform vec3 tint;\n";
|
||||
|
||||
static const gchar *colorize_glsl_source =
|
||||
"float gray = dot (cogl_color_out.rgb, vec3 (0.299, 0.587, 0.114));\n"
|
||||
"cogl_color_out.rgb = gray * tint;\n";
|
||||
|
||||
/* a lame sepia */
|
||||
static const CoglColor default_tint = { 255, 204, 153, 255 };
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_TINT,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterColorizeEffect,
|
||||
clutter_colorize_effect,
|
||||
CLUTTER_TYPE_OFFSCREEN_EFFECT);
|
||||
|
||||
static CoglPipeline *
|
||||
clutter_colorize_effect_create_pipeline (ClutterOffscreenEffect *effect,
|
||||
CoglTexture *texture)
|
||||
{
|
||||
ClutterColorizeEffect *colorize_effect = CLUTTER_COLORIZE_EFFECT (effect);
|
||||
ClutterColorizeEffectPrivate *priv =
|
||||
clutter_colorize_effect_get_instance_private (colorize_effect);
|
||||
|
||||
cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture);
|
||||
|
||||
return g_object_ref (priv->pipeline);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_colorize_effect_dispose (GObject *gobject)
|
||||
{
|
||||
ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (gobject);
|
||||
ClutterColorizeEffectPrivate *priv =
|
||||
clutter_colorize_effect_get_instance_private (self);
|
||||
|
||||
g_clear_object (&priv->pipeline);
|
||||
|
||||
G_OBJECT_CLASS (clutter_colorize_effect_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_colorize_effect_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterColorizeEffect *effect = CLUTTER_COLORIZE_EFFECT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TINT:
|
||||
clutter_colorize_effect_set_tint (effect,
|
||||
cogl_value_get_color (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_colorize_effect_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterColorizeEffect *effect = CLUTTER_COLORIZE_EFFECT (gobject);
|
||||
ClutterColorizeEffectPrivate *priv =
|
||||
clutter_colorize_effect_get_instance_private (effect);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TINT:
|
||||
cogl_value_set_color (value, &priv->tint);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_colorize_effect_class_init (ClutterColorizeEffectClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterOffscreenEffectClass *offscreen_class;
|
||||
|
||||
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
||||
offscreen_class->create_pipeline = clutter_colorize_effect_create_pipeline;
|
||||
|
||||
gobject_class->set_property = clutter_colorize_effect_set_property;
|
||||
gobject_class->get_property = clutter_colorize_effect_get_property;
|
||||
gobject_class->dispose = clutter_colorize_effect_dispose;
|
||||
|
||||
/**
|
||||
* ClutterColorizeEffect:tint:
|
||||
*
|
||||
* The tint to apply to the actor
|
||||
*/
|
||||
obj_props[PROP_TINT] =
|
||||
cogl_param_spec_color ("tint", NULL, NULL,
|
||||
&default_tint,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
update_tint_uniform (ClutterColorizeEffect *self)
|
||||
{
|
||||
ClutterColorizeEffectPrivate *priv =
|
||||
clutter_colorize_effect_get_instance_private (self);
|
||||
if (priv->tint_uniform > -1)
|
||||
{
|
||||
float tint[3] = {
|
||||
priv->tint.red / 255.0f,
|
||||
priv->tint.green / 255.0f,
|
||||
priv->tint.blue / 255.0f,
|
||||
};
|
||||
|
||||
cogl_pipeline_set_uniform_float (priv->pipeline,
|
||||
priv->tint_uniform,
|
||||
3, /* n_components */
|
||||
1, /* count */
|
||||
tint);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_colorize_effect_init (ClutterColorizeEffect *self)
|
||||
{
|
||||
ClutterColorizeEffectClass *klass = CLUTTER_COLORIZE_EFFECT_GET_CLASS (self);
|
||||
ClutterColorizeEffectPrivate *priv =
|
||||
clutter_colorize_effect_get_instance_private (self);
|
||||
if (G_UNLIKELY (klass->base_pipeline == NULL))
|
||||
{
|
||||
CoglSnippet *snippet;
|
||||
ClutterContext *context = _clutter_context_get_default ();
|
||||
ClutterBackend *backend = clutter_context_get_backend (context);
|
||||
CoglContext *cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
|
||||
klass->base_pipeline = cogl_pipeline_new (cogl_context);
|
||||
cogl_pipeline_set_static_name (klass->base_pipeline, "ClutterColorize");
|
||||
|
||||
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
|
||||
colorize_glsl_declarations,
|
||||
colorize_glsl_source);
|
||||
cogl_pipeline_add_snippet (klass->base_pipeline, snippet);
|
||||
g_object_unref (snippet);
|
||||
|
||||
cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0);
|
||||
}
|
||||
|
||||
priv->pipeline = cogl_pipeline_copy (klass->base_pipeline);
|
||||
|
||||
priv->tint_uniform =
|
||||
cogl_pipeline_get_uniform_location (priv->pipeline, "tint");
|
||||
|
||||
priv->tint = default_tint;
|
||||
|
||||
update_tint_uniform (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_colorize_effect_new:
|
||||
* @tint: the color to be used
|
||||
*
|
||||
* Creates a new #ClutterColorizeEffect to be used with
|
||||
* [method@Clutter.Actor.add_effect]
|
||||
*
|
||||
* Return value: the newly created #ClutterColorizeEffect or %NULL
|
||||
*/
|
||||
ClutterEffect *
|
||||
clutter_colorize_effect_new (const CoglColor *tint)
|
||||
{
|
||||
return g_object_new (CLUTTER_TYPE_COLORIZE_EFFECT,
|
||||
"tint", tint,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_colorize_effect_set_tint:
|
||||
* @effect: a #ClutterColorizeEffect
|
||||
* @tint: the color to be used
|
||||
*
|
||||
* Sets the tint to be used when colorizing
|
||||
*/
|
||||
void
|
||||
clutter_colorize_effect_set_tint (ClutterColorizeEffect *effect,
|
||||
const CoglColor *tint)
|
||||
{
|
||||
ClutterColorizeEffectPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_COLORIZE_EFFECT (effect));
|
||||
|
||||
priv = clutter_colorize_effect_get_instance_private (effect);
|
||||
priv->tint = *tint;
|
||||
|
||||
update_tint_uniform (effect);
|
||||
|
||||
clutter_effect_queue_repaint (CLUTTER_EFFECT (effect));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_TINT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_colorize_effect_get_tint:
|
||||
* @effect: a #ClutterColorizeEffect
|
||||
* @tint: (out caller-allocates): return location for the color used
|
||||
*
|
||||
* Retrieves the tint used by @effect
|
||||
*/
|
||||
void
|
||||
clutter_colorize_effect_get_tint (ClutterColorizeEffect *effect,
|
||||
CoglColor *tint)
|
||||
{
|
||||
ClutterColorizeEffectPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_COLORIZE_EFFECT (effect));
|
||||
g_return_if_fail (tint != NULL);
|
||||
|
||||
priv = clutter_colorize_effect_get_instance_private (effect);
|
||||
*tint = priv->tint;
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-effect.h"
|
||||
#include "clutter/clutter-offscreen-effect.h"
|
||||
#include "cogl/cogl-color.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_COLORIZE_EFFECT (clutter_colorize_effect_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterColorizeEffect,
|
||||
clutter_colorize_effect,
|
||||
CLUTTER, COLORIZE_EFFECT,
|
||||
ClutterOffscreenEffect)
|
||||
|
||||
struct _ClutterColorizeEffectClass
|
||||
{
|
||||
ClutterOffscreenEffectClass parent_class;
|
||||
|
||||
CoglPipeline *base_pipeline;
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterEffect *clutter_colorize_effect_new (const CoglColor *tint);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_colorize_effect_set_tint (ClutterColorizeEffect *effect,
|
||||
const CoglColor *tint);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_colorize_effect_get_tint (ClutterColorizeEffect *effect,
|
||||
CoglColor *tint);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "clutter/clutter-constraint.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean clutter_constraint_update_allocation (ClutterConstraint *constraint,
|
||||
ClutterActor *actor,
|
||||
ClutterActorBox *allocation);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,218 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterConstraint:
|
||||
*
|
||||
* Abstract class for constraints on position or size
|
||||
*
|
||||
* #ClutterConstraint is a base abstract class for modifiers of a #ClutterActor
|
||||
* position or size.
|
||||
*
|
||||
* A #ClutterConstraint sub-class should contain the logic for modifying
|
||||
* the position or size of the #ClutterActor to which it is applied, by
|
||||
* updating the actor's allocation. Each #ClutterConstraint can change the
|
||||
* allocation of the actor to which they are applied by overriding the
|
||||
* [vfunc@Clutter.Constraint.update_allocation] virtual function.
|
||||
*
|
||||
* ## Using Constraints
|
||||
*
|
||||
* Constraints can be used with fixed layout managers, like
|
||||
* #ClutterFixedLayout, or with actors implicitly using a fixed layout
|
||||
* manager, like #ClutterGroup and #ClutterStage.
|
||||
*
|
||||
* Constraints provide a way to build user interfaces by using
|
||||
* relations between #ClutterActors, without explicit fixed
|
||||
* positioning and sizing, similarly to how fluid layout managers like
|
||||
* #ClutterBoxLayout lay out their children.
|
||||
*
|
||||
* Constraints are attached to a #ClutterActor, and are available
|
||||
* for inspection using [method@Clutter.Actor.get_constraints].
|
||||
*
|
||||
* Clutter provides different implementation of the #ClutterConstraint
|
||||
* abstract class, for instance:
|
||||
*
|
||||
* - #ClutterAlignConstraint, a constraint that can be used to align
|
||||
* an actor to another one on either the horizontal or the vertical
|
||||
* axis, using a normalized value between 0 and 1.
|
||||
* - #ClutterBindConstraint, a constraint binds the X, Y, width or height
|
||||
* of an actor to the corresponding position or size of a source actor,
|
||||
* with or without an offset.
|
||||
* - #ClutterSnapConstraint, a constraint that "snaps" together the edges
|
||||
* of two #ClutterActors; if an actor uses two constraints on both its
|
||||
* horizontal or vertical edges then it can also expand to fit the empty
|
||||
* space.
|
||||
*
|
||||
* It is important to note that Clutter does not avoid loops or
|
||||
* competing constraints; if two or more #ClutterConstraints
|
||||
* are operating on the same positional or dimensional attributes of an
|
||||
* actor, or if the constraints on two different actors depend on each
|
||||
* other, then the behavior is undefined.
|
||||
*
|
||||
* ## Implementing a ClutterConstraint
|
||||
*
|
||||
* Creating a sub-class of #ClutterConstraint requires the
|
||||
* implementation of the [vfunc@Clutter.Constraint.update_allocation]
|
||||
* virtual function.
|
||||
*
|
||||
* The `update_allocation()` virtual function is called during the
|
||||
* allocation sequence of a #ClutterActor, and allows any #ClutterConstraint
|
||||
* attached to that actor to modify the allocation before it is passed to
|
||||
* the actor's #ClutterActorClass.allocate() implementation.
|
||||
*
|
||||
* The #ClutterActorBox passed to the `update_allocation()` implementation
|
||||
* contains the original allocation of the #ClutterActor, plus the eventual
|
||||
* modifications applied by the other #ClutterConstraints, in the same order
|
||||
* the constraints have been applied to the actor.
|
||||
*
|
||||
* It is not necessary for a #ClutterConstraint sub-class to chain
|
||||
* up to the parent's implementation.
|
||||
*
|
||||
* If a #ClutterConstraint is parametrized - i.e. if it contains
|
||||
* properties that affect the way the constraint is implemented - it should
|
||||
* call clutter_actor_queue_relayout() on the actor to which it is attached
|
||||
* to whenever any parameter is changed. The actor to which it is attached
|
||||
* can be recovered at any point using clutter_actor_meta_get_actor().
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "clutter/clutter-constraint-private.h"
|
||||
|
||||
#include "clutter/clutter-actor.h"
|
||||
#include "clutter/clutter-actor-meta-private.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (ClutterConstraint,
|
||||
clutter_constraint,
|
||||
CLUTTER_TYPE_ACTOR_META);
|
||||
|
||||
static void
|
||||
constraint_update_allocation (ClutterConstraint *constraint,
|
||||
ClutterActor *actor,
|
||||
ClutterActorBox *allocation)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_update_preferred_size (ClutterConstraint *constraint,
|
||||
ClutterActor *actor,
|
||||
ClutterOrientation direction,
|
||||
float for_size,
|
||||
float *minimum_size,
|
||||
float *natural_size)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_constraint_set_enabled (ClutterActorMeta *meta,
|
||||
gboolean is_enabled)
|
||||
{
|
||||
ClutterActorMetaClass *parent_class =
|
||||
CLUTTER_ACTOR_META_CLASS (clutter_constraint_parent_class);
|
||||
ClutterActor *actor;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (meta);
|
||||
if (actor)
|
||||
clutter_actor_queue_relayout (actor);
|
||||
|
||||
parent_class->set_enabled (meta, is_enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_constraint_class_init (ClutterConstraintClass *klass)
|
||||
{
|
||||
ClutterActorMetaClass *actor_meta_class = CLUTTER_ACTOR_META_CLASS (klass);
|
||||
|
||||
actor_meta_class->set_enabled = clutter_constraint_set_enabled;
|
||||
|
||||
klass->update_allocation = constraint_update_allocation;
|
||||
klass->update_preferred_size = constraint_update_preferred_size;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_constraint_init (ClutterConstraint *self)
|
||||
{
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* clutter_constraint_update_allocation:
|
||||
* @constraint: a #ClutterConstraint
|
||||
* @actor: a #ClutterActor
|
||||
* @allocation: (inout): the allocation to modify
|
||||
*
|
||||
* Asks the @constraint to update the @allocation of a #ClutterActor.
|
||||
*
|
||||
* Returns: %TRUE if the allocation was updated
|
||||
*/
|
||||
gboolean
|
||||
clutter_constraint_update_allocation (ClutterConstraint *constraint,
|
||||
ClutterActor *actor,
|
||||
ClutterActorBox *allocation)
|
||||
{
|
||||
ClutterActorBox old_alloc;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_CONSTRAINT (constraint), FALSE);
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE);
|
||||
g_return_val_if_fail (allocation != NULL, FALSE);
|
||||
|
||||
old_alloc = *allocation;
|
||||
|
||||
CLUTTER_CONSTRAINT_GET_CLASS (constraint)->update_allocation (constraint,
|
||||
actor,
|
||||
allocation);
|
||||
|
||||
return !clutter_actor_box_equal (allocation, &old_alloc);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_constraint_update_preferred_size:
|
||||
* @constraint: a #ClutterConstraint
|
||||
* @actor: a #ClutterActor
|
||||
* @direction: a #ClutterOrientation
|
||||
* @for_size: the size in the opposite direction
|
||||
* @minimum_size: (inout): the minimum size to modify
|
||||
* @natural_size: (inout): the natural size to modify
|
||||
*
|
||||
* Asks the @constraint to update the size request of a #ClutterActor.
|
||||
*/
|
||||
void
|
||||
clutter_constraint_update_preferred_size (ClutterConstraint *constraint,
|
||||
ClutterActor *actor,
|
||||
ClutterOrientation direction,
|
||||
float for_size,
|
||||
float *minimum_size,
|
||||
float *natural_size)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_CONSTRAINT (constraint));
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||
|
||||
CLUTTER_CONSTRAINT_GET_CLASS (constraint)->update_preferred_size (constraint, actor,
|
||||
direction,
|
||||
for_size,
|
||||
minimum_size,
|
||||
natural_size);
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-actor-meta.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_CONSTRAINT (clutter_constraint_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterConstraint,
|
||||
clutter_constraint,
|
||||
CLUTTER,
|
||||
CONSTRAINT,
|
||||
ClutterActorMeta)
|
||||
|
||||
/**
|
||||
* ClutterConstraintClass:
|
||||
* @update_allocation: virtual function used to update the allocation
|
||||
* of the #ClutterActor using the #ClutterConstraint
|
||||
* @update_preferred_size: virtual function used to update the preferred
|
||||
* size of the #ClutterActor using the #ClutterConstraint; optional,
|
||||
* since 1.22
|
||||
*
|
||||
* The #ClutterConstraintClass structure contains
|
||||
* only private data
|
||||
*/
|
||||
struct _ClutterConstraintClass
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterActorMetaClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
void (* update_allocation) (ClutterConstraint *constraint,
|
||||
ClutterActor *actor,
|
||||
ClutterActorBox *allocation);
|
||||
|
||||
void (* update_preferred_size) (ClutterConstraint *constraint,
|
||||
ClutterActor *actor,
|
||||
ClutterOrientation direction,
|
||||
float for_size,
|
||||
float *minimum_size,
|
||||
float *natural_size);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_constraint_update_preferred_size (ClutterConstraint *constraint,
|
||||
ClutterActor *actor,
|
||||
ClutterOrientation direction,
|
||||
float for_size,
|
||||
float *minimum_size,
|
||||
float *natural_size);
|
||||
|
||||
/* ClutterActor API */
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_add_constraint (ClutterActor *self,
|
||||
ClutterConstraint *constraint);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_add_constraint_with_name (ClutterActor *self,
|
||||
const gchar *name,
|
||||
ClutterConstraint *constraint);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_remove_constraint (ClutterActor *self,
|
||||
ClutterConstraint *constraint);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_remove_constraint_by_name (ClutterActor *self,
|
||||
const gchar *name);
|
||||
CLUTTER_EXPORT
|
||||
GList * clutter_actor_get_constraints (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
ClutterConstraint *clutter_actor_get_constraint (ClutterActor *self,
|
||||
const gchar *name);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_clear_constraints (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_has_constraints (ClutterActor *self);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2011 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "clutter/clutter-content.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void _clutter_content_attached (ClutterContent *content,
|
||||
ClutterActor *actor);
|
||||
void _clutter_content_detached (ClutterContent *content,
|
||||
ClutterActor *actor);
|
||||
|
||||
void _clutter_content_paint_content (ClutterContent *content,
|
||||
ClutterActor *actor,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,339 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2011 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterContent:
|
||||
*
|
||||
* Delegate for painting the content of an actor
|
||||
*
|
||||
* #ClutterContent is an interface to implement types responsible for
|
||||
* painting the content of a [class@Actor].
|
||||
*
|
||||
* Multiple actors can use the same #ClutterContent instance, in order
|
||||
* to share the resources associated with painting the same content..
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-actor-private.h"
|
||||
#include "clutter/clutter-content-private.h"
|
||||
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-marshal.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
enum
|
||||
{
|
||||
ATTACHED,
|
||||
DETACHED,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static GQuark quark_content_actors = 0;
|
||||
|
||||
static guint content_signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
G_DEFINE_INTERFACE (ClutterContent, clutter_content, G_TYPE_OBJECT)
|
||||
|
||||
static gboolean
|
||||
clutter_content_real_get_preferred_size (ClutterContent *content,
|
||||
gfloat *width,
|
||||
gfloat *height)
|
||||
{
|
||||
if (width != NULL)
|
||||
*width = 0.f;
|
||||
|
||||
if (height != NULL)
|
||||
*height = 0.f;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_content_real_attached (ClutterContent *content,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_content_real_detached (ClutterContent *content,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_content_real_invalidate (ClutterContent *content)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_content_real_invalidate_size (ClutterContent *content)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_content_real_paint_content (ClutterContent *content,
|
||||
ClutterActor *actor,
|
||||
ClutterPaintNode *context,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_content_default_init (ClutterContentInterface *iface)
|
||||
{
|
||||
quark_content_actors = g_quark_from_static_string ("-clutter-content-actors");
|
||||
|
||||
iface->get_preferred_size = clutter_content_real_get_preferred_size;
|
||||
iface->paint_content = clutter_content_real_paint_content;
|
||||
iface->attached = clutter_content_real_attached;
|
||||
iface->detached = clutter_content_real_detached;
|
||||
iface->invalidate = clutter_content_real_invalidate;
|
||||
iface->invalidate_size = clutter_content_real_invalidate_size;
|
||||
|
||||
/**
|
||||
* ClutterContent::attached:
|
||||
* @content: the object that emitted the signal
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* This signal is emitted each time a #ClutterContent implementation is
|
||||
* assigned to a #ClutterActor.
|
||||
*/
|
||||
content_signals[ATTACHED] =
|
||||
g_signal_new (I_("attached"),
|
||||
G_TYPE_FROM_INTERFACE (iface),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterContentInterface, attached),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
|
||||
/**
|
||||
* ClutterContent::detached:
|
||||
* @content: the object that emitted the signal
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* This signal is emitted each time a #ClutterContent implementation is
|
||||
* removed from a #ClutterActor.
|
||||
*/
|
||||
content_signals[DETACHED] =
|
||||
g_signal_new (I_("detached"),
|
||||
G_TYPE_FROM_INTERFACE (iface),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterContentInterface, detached),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_content_invalidate:
|
||||
* @content: a #ClutterContent
|
||||
*
|
||||
* Invalidates a #ClutterContent.
|
||||
*
|
||||
* This function should be called by #ClutterContent implementations when
|
||||
* they change the way a the content should be painted regardless of the
|
||||
* actor state.
|
||||
*/
|
||||
void
|
||||
clutter_content_invalidate (ClutterContent *content)
|
||||
{
|
||||
GHashTable *actors;
|
||||
GHashTableIter iter;
|
||||
gpointer key_p, value_p;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_CONTENT (content));
|
||||
|
||||
CLUTTER_CONTENT_GET_IFACE (content)->invalidate (content);
|
||||
|
||||
actors = g_object_get_qdata (G_OBJECT (content), quark_content_actors);
|
||||
if (actors == NULL)
|
||||
return;
|
||||
|
||||
g_hash_table_iter_init (&iter, actors);
|
||||
while (g_hash_table_iter_next (&iter, &key_p, &value_p))
|
||||
{
|
||||
ClutterActor *actor = key_p;
|
||||
|
||||
g_assert (actor != NULL);
|
||||
|
||||
clutter_actor_queue_redraw (actor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_content_invalidate_size:
|
||||
* @content: a #ClutterContent
|
||||
*
|
||||
* Signals that @content's size changed. Attached actors with request mode
|
||||
* set to %CLUTTER_REQUEST_CONTENT_SIZE will have a relayout queued.
|
||||
*
|
||||
* Attached actors with other request modes are not redrawn. To redraw them
|
||||
* too, use [method@Clutter.Content.invalidate].
|
||||
*/
|
||||
void
|
||||
clutter_content_invalidate_size (ClutterContent *content)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
GHashTable *actors;
|
||||
GHashTableIter iter;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_CONTENT (content));
|
||||
|
||||
CLUTTER_CONTENT_GET_IFACE (content)->invalidate_size (content);
|
||||
|
||||
actors = g_object_get_qdata (G_OBJECT (content), quark_content_actors);
|
||||
if (actors == NULL)
|
||||
return;
|
||||
|
||||
g_hash_table_iter_init (&iter, actors);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &actor, NULL))
|
||||
{
|
||||
ClutterRequestMode request_mode;
|
||||
|
||||
g_assert (actor != NULL);
|
||||
|
||||
request_mode = clutter_actor_get_request_mode (actor);
|
||||
|
||||
if (request_mode == CLUTTER_REQUEST_CONTENT_SIZE)
|
||||
_clutter_actor_queue_only_relayout (actor);
|
||||
}
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* _clutter_content_attached:
|
||||
* @content: a #ClutterContent
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* Attaches @actor to the @content.
|
||||
*
|
||||
* This function should be used internally every time a #ClutterActor
|
||||
* is associated to a #ClutterContent, to set up a backpointer from
|
||||
* the @content to the @actor.
|
||||
*
|
||||
* This function will invoke the [vfunc@Clutter.Content.attached] virtual
|
||||
* function.
|
||||
*/
|
||||
void
|
||||
_clutter_content_attached (ClutterContent *content,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
GObject *obj = G_OBJECT (content);
|
||||
GHashTable *actors;
|
||||
|
||||
actors = g_object_get_qdata (obj, quark_content_actors);
|
||||
if (actors == NULL)
|
||||
{
|
||||
actors = g_hash_table_new (NULL, NULL);
|
||||
g_object_set_qdata_full (obj, quark_content_actors,
|
||||
actors,
|
||||
(GDestroyNotify) g_hash_table_unref);
|
||||
}
|
||||
|
||||
g_hash_table_insert (actors, actor, actor);
|
||||
|
||||
g_signal_emit (content, content_signals[ATTACHED], 0, actor);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* _clutter_content_detached:
|
||||
* @content: a #ClutterContent
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* Detaches @actor from @content.
|
||||
*
|
||||
* This function should be used internally every time a #ClutterActor
|
||||
* removes the association with a #ClutterContent.
|
||||
*
|
||||
* This function will invoke the [vfunc@Clutter.Content.detached] virtual
|
||||
* function.
|
||||
*/
|
||||
void
|
||||
_clutter_content_detached (ClutterContent *content,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
GObject *obj = G_OBJECT (content);
|
||||
GHashTable *actors;
|
||||
|
||||
actors = g_object_get_qdata (obj, quark_content_actors);
|
||||
g_assert (actors != NULL);
|
||||
|
||||
g_hash_table_remove (actors, actor);
|
||||
|
||||
if (g_hash_table_size (actors) == 0)
|
||||
g_object_set_qdata (obj, quark_content_actors, NULL);
|
||||
|
||||
g_signal_emit (content, content_signals[DETACHED], 0, actor);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* _clutter_content_paint_content:
|
||||
* @content: a #ClutterContent
|
||||
* @actor: a #ClutterActor
|
||||
* @node: a #ClutterPaintNode
|
||||
* @paint_context: a #ClutterPaintContext
|
||||
*
|
||||
* Creates the render tree for the @content and @actor.
|
||||
*
|
||||
* This function will invoke the [vfunc@Clutter.Content.paint_content]
|
||||
* virtual function.
|
||||
*/
|
||||
void
|
||||
_clutter_content_paint_content (ClutterContent *content,
|
||||
ClutterActor *actor,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
CLUTTER_CONTENT_GET_IFACE (content)->paint_content (content, actor, node,
|
||||
paint_context);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_content_get_preferred_size:
|
||||
* @content: a #ClutterContent
|
||||
* @width: (out) (optional): return location for the natural width of the content
|
||||
* @height: (out) (optional): return location for the natural height of the content
|
||||
*
|
||||
* Retrieves the natural size of the @content, if any.
|
||||
*
|
||||
* The natural size of a #ClutterContent is defined as the size the content
|
||||
* would have regardless of the allocation of the actor that is painting it,
|
||||
* for instance the size of an image data.
|
||||
*
|
||||
* Return value: %TRUE if the content has a preferred size, and %FALSE
|
||||
* otherwise
|
||||
*/
|
||||
gboolean
|
||||
clutter_content_get_preferred_size (ClutterContent *content,
|
||||
gfloat *width,
|
||||
gfloat *height)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_CONTENT (content), FALSE);
|
||||
|
||||
return CLUTTER_CONTENT_GET_IFACE (content)->get_preferred_size (content,
|
||||
width,
|
||||
height);
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2012 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_CONTENT (clutter_content_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_INTERFACE (ClutterContent, clutter_content, CLUTTER, CONTENT, GObject)
|
||||
|
||||
/**
|
||||
* ClutterContentInterface:
|
||||
* @get_preferred_size: virtual function; should be overridden by subclasses
|
||||
* of #ClutterContent that have a natural size
|
||||
* @paint_content: virtual function; called each time the content needs to
|
||||
* paint itself
|
||||
* @attached: virtual function; called each time a #ClutterContent is attached
|
||||
* to a #ClutterActor.
|
||||
* @detached: virtual function; called each time a #ClutterContent is detached
|
||||
* from a #ClutterActor.
|
||||
* @invalidate: virtual function; called each time a #ClutterContent state
|
||||
* is changed.
|
||||
*
|
||||
* The #ClutterContentInterface structure contains only
|
||||
* private data.
|
||||
*/
|
||||
struct _ClutterContentInterface
|
||||
{
|
||||
/*< private >*/
|
||||
GTypeInterface g_iface;
|
||||
|
||||
/*< public >*/
|
||||
gboolean (* get_preferred_size) (ClutterContent *content,
|
||||
gfloat *width,
|
||||
gfloat *height);
|
||||
void (* paint_content) (ClutterContent *content,
|
||||
ClutterActor *actor,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context);
|
||||
|
||||
void (* attached) (ClutterContent *content,
|
||||
ClutterActor *actor);
|
||||
void (* detached) (ClutterContent *content,
|
||||
ClutterActor *actor);
|
||||
|
||||
void (* invalidate) (ClutterContent *content);
|
||||
|
||||
void (* invalidate_size) (ClutterContent *content);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_content_get_preferred_size (ClutterContent *content,
|
||||
gfloat *width,
|
||||
gfloat *height);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_content_invalidate (ClutterContent *content);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_content_invalidate_size (ClutterContent *content);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 OpenedHand
|
||||
* Copyright (C) 2023 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef HAVE_FONTS
|
||||
#include <pango/pango.h>
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-context.h"
|
||||
#include "clutter-stage-manager-private.h"
|
||||
|
||||
struct _ClutterContext
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
ClutterBackend *backend;
|
||||
ClutterStageManager *stage_manager;
|
||||
|
||||
GAsyncQueue *events_queue;
|
||||
|
||||
/* the event filters added via clutter_event_add_filter. these are
|
||||
* ordered from least recently added to most recently added */
|
||||
GList *event_filters;
|
||||
|
||||
#ifdef HAVE_FONTS
|
||||
PangoRenderer *font_renderer;
|
||||
PangoFontMap *font_map;
|
||||
#endif
|
||||
|
||||
GSList *current_event;
|
||||
|
||||
GList *repaint_funcs;
|
||||
guint last_repaint_id;
|
||||
|
||||
ClutterSettings *settings;
|
||||
|
||||
gboolean show_fps;
|
||||
};
|
||||
|
||||
ClutterStageManager * clutter_context_get_stage_manager (ClutterContext *context);
|
||||
|
||||
gboolean clutter_context_get_show_fps (ClutterContext *context);
|
||||
|
||||
#ifdef HAVE_FONTS
|
||||
PangoRenderer * clutter_context_get_font_renderer (ClutterContext *context);
|
||||
|
||||
/**
|
||||
* clutter_context_get_pango_fontmap: (skip)
|
||||
*/
|
||||
PangoFontMap * clutter_context_get_pango_fontmap (ClutterContext *context);
|
||||
#endif
|
||||
@@ -1,413 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 OpenedHand
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-context-private.h"
|
||||
|
||||
#ifdef HAVE_FONTS
|
||||
#include <hb-glib.h>
|
||||
#include <pango/pangocairo.h>
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-accessibility-private.h"
|
||||
#include "clutter/clutter-backend-private.h"
|
||||
#include "clutter/clutter-color-manager.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-main.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#include "clutter/clutter-paint-node-private.h"
|
||||
#include "clutter/clutter-settings-private.h"
|
||||
#ifdef HAVE_FONTS
|
||||
#include "clutter/pango/clutter-pango-private.h"
|
||||
#endif
|
||||
|
||||
static gboolean clutter_show_fps = FALSE;
|
||||
static gboolean clutter_enable_accessibility = TRUE;
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
static const GDebugKey clutter_debug_keys[] = {
|
||||
{ "misc", CLUTTER_DEBUG_MISC },
|
||||
{ "actor", CLUTTER_DEBUG_ACTOR },
|
||||
{ "texture", CLUTTER_DEBUG_TEXTURE },
|
||||
{ "event", CLUTTER_DEBUG_EVENT },
|
||||
{ "paint", CLUTTER_DEBUG_PAINT },
|
||||
{ "pick", CLUTTER_DEBUG_PICK },
|
||||
{ "pango", CLUTTER_DEBUG_PANGO },
|
||||
{ "backend", CLUTTER_DEBUG_BACKEND },
|
||||
{ "scheduler", CLUTTER_DEBUG_SCHEDULER },
|
||||
{ "script", CLUTTER_DEBUG_SCRIPT },
|
||||
{ "shader", CLUTTER_DEBUG_SHADER },
|
||||
{ "animation", CLUTTER_DEBUG_ANIMATION },
|
||||
{ "layout", CLUTTER_DEBUG_LAYOUT },
|
||||
{ "clipping", CLUTTER_DEBUG_CLIPPING },
|
||||
{ "oob-transforms", CLUTTER_DEBUG_OOB_TRANSFORMS },
|
||||
{ "frame-timings", CLUTTER_DEBUG_FRAME_TIMINGS },
|
||||
{ "detailed-trace", CLUTTER_DEBUG_DETAILED_TRACE },
|
||||
{ "grabs", CLUTTER_DEBUG_GRABS },
|
||||
{ "frame-clock", CLUTTER_DEBUG_FRAME_CLOCK },
|
||||
{ "gestures", CLUTTER_DEBUG_GESTURES },
|
||||
};
|
||||
#endif /* CLUTTER_ENABLE_DEBUG */
|
||||
|
||||
static const GDebugKey clutter_pick_debug_keys[] = {
|
||||
{ "nop-picking", CLUTTER_DEBUG_NOP_PICKING },
|
||||
};
|
||||
|
||||
static const GDebugKey clutter_paint_debug_keys[] = {
|
||||
{ "disable-swap-events", CLUTTER_DEBUG_DISABLE_SWAP_EVENTS },
|
||||
{ "disable-clipped-redraws", CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS },
|
||||
{ "redraws", CLUTTER_DEBUG_REDRAWS },
|
||||
{ "paint-volumes", CLUTTER_DEBUG_PAINT_VOLUMES },
|
||||
{ "disable-culling", CLUTTER_DEBUG_DISABLE_CULLING },
|
||||
{ "disable-offscreen-redirect", CLUTTER_DEBUG_DISABLE_OFFSCREEN_REDIRECT },
|
||||
{ "continuous-redraw", CLUTTER_DEBUG_CONTINUOUS_REDRAW },
|
||||
{ "paint-deform-tiles", CLUTTER_DEBUG_PAINT_DEFORM_TILES },
|
||||
{ "damage-region", CLUTTER_DEBUG_PAINT_DAMAGE_REGION },
|
||||
{ "disable-dynamic-max-render-time", CLUTTER_DEBUG_DISABLE_DYNAMIC_MAX_RENDER_TIME },
|
||||
{ "max-render-time", CLUTTER_DEBUG_PAINT_MAX_RENDER_TIME },
|
||||
{ "disable-triple-buffering", CLUTTER_DEBUG_DISABLE_TRIPLE_BUFFERING },
|
||||
};
|
||||
|
||||
typedef struct _ClutterContextPrivate
|
||||
{
|
||||
ClutterTextDirection text_direction;
|
||||
|
||||
ClutterColorManager *color_manager;
|
||||
ClutterPipelineCache *pipeline_cache;
|
||||
} ClutterContextPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterContext, clutter_context, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
clutter_context_dispose (GObject *object)
|
||||
{
|
||||
ClutterContext *context = CLUTTER_CONTEXT (object);
|
||||
ClutterContextPrivate *priv = clutter_context_get_instance_private (context);
|
||||
|
||||
g_clear_object (&priv->pipeline_cache);
|
||||
g_clear_object (&priv->color_manager);
|
||||
g_clear_pointer (&context->events_queue, g_async_queue_unref);
|
||||
g_clear_pointer (&context->backend, clutter_backend_destroy);
|
||||
g_clear_object (&context->stage_manager);
|
||||
g_clear_object (&context->settings);
|
||||
#ifdef HAVE_FONTS
|
||||
g_clear_object (&context->font_map);
|
||||
#endif
|
||||
|
||||
G_OBJECT_CLASS (clutter_context_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_context_class_init (ClutterContextClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = clutter_context_dispose;
|
||||
|
||||
clutter_interval_register_progress_funcs ();
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_context_init (ClutterContext *context)
|
||||
{
|
||||
ClutterContextPrivate *priv = clutter_context_get_instance_private (context);
|
||||
|
||||
priv->text_direction = CLUTTER_TEXT_DIRECTION_LTR;
|
||||
}
|
||||
|
||||
ClutterTextDirection
|
||||
clutter_get_text_direction (void)
|
||||
{
|
||||
ClutterTextDirection dir = CLUTTER_TEXT_DIRECTION_LTR;
|
||||
const gchar *direction;
|
||||
|
||||
direction = g_getenv ("CLUTTER_TEXT_DIRECTION");
|
||||
if (direction && *direction != '\0')
|
||||
{
|
||||
if (strcmp (direction, "rtl") == 0)
|
||||
dir = CLUTTER_TEXT_DIRECTION_RTL;
|
||||
else if (strcmp (direction, "ltr") == 0)
|
||||
dir = CLUTTER_TEXT_DIRECTION_LTR;
|
||||
}
|
||||
#ifdef HAVE_FONTS
|
||||
else
|
||||
{
|
||||
PangoLanguage *language;
|
||||
const PangoScript *scripts;
|
||||
int n_scripts, i;
|
||||
|
||||
language = pango_language_get_default ();
|
||||
scripts = pango_language_get_scripts (language, &n_scripts);
|
||||
|
||||
for (i = 0; i < n_scripts; i++)
|
||||
{
|
||||
hb_script_t script;
|
||||
hb_direction_t text_dir;
|
||||
|
||||
script = hb_glib_script_to_script ((GUnicodeScript) scripts[i]);
|
||||
text_dir = hb_script_get_horizontal_direction (script);
|
||||
|
||||
if (text_dir == HB_DIRECTION_LTR)
|
||||
dir = CLUTTER_TEXT_DIRECTION_LTR;
|
||||
else if (text_dir == HB_DIRECTION_RTL)
|
||||
dir = CLUTTER_TEXT_DIRECTION_RTL;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CLUTTER_NOTE (MISC, "Text direction: %s",
|
||||
dir == CLUTTER_TEXT_DIRECTION_RTL ? "rtl" : "ltr");
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_context_init_real (ClutterContext *context,
|
||||
GError **error)
|
||||
{
|
||||
ClutterContextPrivate *priv = clutter_context_get_instance_private (context);
|
||||
|
||||
/* If we are displaying the regions that would get redrawn with clipped
|
||||
* redraws enabled we actually have to disable the clipped redrawing
|
||||
* because otherwise we end up with nasty trails of rectangles everywhere.
|
||||
*/
|
||||
if (clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS)
|
||||
clutter_paint_debug_flags |= CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS;
|
||||
|
||||
/* The same is true when drawing the outlines of paint volumes... */
|
||||
if (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_VOLUMES)
|
||||
{
|
||||
clutter_paint_debug_flags |=
|
||||
CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS | CLUTTER_DEBUG_DISABLE_CULLING;
|
||||
}
|
||||
|
||||
if (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION)
|
||||
g_message ("Enabling damaged region");
|
||||
|
||||
if (!_clutter_backend_create_context (context->backend, error))
|
||||
return FALSE;
|
||||
|
||||
priv->text_direction = clutter_get_text_direction ();
|
||||
|
||||
/* Initialize a11y */
|
||||
if (clutter_enable_accessibility)
|
||||
{
|
||||
_clutter_accessibility_override_atk_util ();
|
||||
CLUTTER_NOTE (MISC, "Clutter Accessibility initialized");
|
||||
}
|
||||
|
||||
/* Initialize types required for paint nodes */
|
||||
clutter_paint_node_init_types (context->backend);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
init_clutter_debug (ClutterContext *context)
|
||||
{
|
||||
const char *env_string;
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
env_string = g_getenv ("CLUTTER_DEBUG");
|
||||
if (env_string != NULL)
|
||||
{
|
||||
clutter_debug_flags =
|
||||
g_parse_debug_string (env_string,
|
||||
clutter_debug_keys,
|
||||
G_N_ELEMENTS (clutter_debug_keys));
|
||||
env_string = NULL;
|
||||
}
|
||||
#endif /* CLUTTER_ENABLE_DEBUG */
|
||||
|
||||
env_string = g_getenv ("CLUTTER_PICK");
|
||||
if (env_string != NULL)
|
||||
{
|
||||
clutter_pick_debug_flags =
|
||||
g_parse_debug_string (env_string,
|
||||
clutter_pick_debug_keys,
|
||||
G_N_ELEMENTS (clutter_pick_debug_keys));
|
||||
env_string = NULL;
|
||||
}
|
||||
|
||||
env_string = g_getenv ("CLUTTER_PAINT");
|
||||
if (env_string != NULL)
|
||||
{
|
||||
clutter_paint_debug_flags =
|
||||
g_parse_debug_string (env_string,
|
||||
clutter_paint_debug_keys,
|
||||
G_N_ELEMENTS (clutter_paint_debug_keys));
|
||||
env_string = NULL;
|
||||
}
|
||||
|
||||
env_string = g_getenv ("CLUTTER_SHOW_FPS");
|
||||
if (env_string)
|
||||
clutter_show_fps = TRUE;
|
||||
|
||||
env_string = g_getenv ("CLUTTER_DISABLE_ACCESSIBILITY");
|
||||
if (env_string)
|
||||
clutter_enable_accessibility = FALSE;
|
||||
}
|
||||
|
||||
ClutterContext *
|
||||
clutter_context_new (ClutterBackendConstructor backend_constructor,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
ClutterContext *context;
|
||||
ClutterContextPrivate *priv;
|
||||
|
||||
context = g_object_new (CLUTTER_TYPE_CONTEXT, NULL);
|
||||
priv = clutter_context_get_instance_private (context);
|
||||
|
||||
init_clutter_debug (context);
|
||||
context->show_fps = clutter_show_fps;
|
||||
|
||||
context->backend = backend_constructor (context, user_data);
|
||||
context->settings = g_object_new (CLUTTER_TYPE_SETTINGS, NULL);
|
||||
_clutter_settings_set_backend (context->settings,
|
||||
context->backend);
|
||||
|
||||
context->stage_manager = g_object_new (CLUTTER_TYPE_STAGE_MANAGER, NULL);
|
||||
|
||||
context->events_queue =
|
||||
g_async_queue_new_full ((GDestroyNotify) clutter_event_free);
|
||||
context->last_repaint_id = 1;
|
||||
|
||||
priv->color_manager = g_object_new (CLUTTER_TYPE_COLOR_MANAGER,
|
||||
"context", context,
|
||||
NULL);
|
||||
priv->pipeline_cache = g_object_new (CLUTTER_TYPE_PIPELINE_CACHE, NULL);
|
||||
|
||||
if (!clutter_context_init_real (context, error))
|
||||
return NULL;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_context_destroy (ClutterContext *context)
|
||||
{
|
||||
g_object_run_dispose (G_OBJECT (context));
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
ClutterBackend *
|
||||
clutter_context_get_backend (ClutterContext *context)
|
||||
{
|
||||
return context->backend;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FONTS
|
||||
PangoFontMap *
|
||||
clutter_context_get_pango_fontmap (ClutterContext *context)
|
||||
{
|
||||
PangoFontMap *font_map;
|
||||
PangoRenderer *font_renderer;
|
||||
gdouble resolution;
|
||||
ClutterBackend *backend;
|
||||
CoglContext *cogl_context;
|
||||
|
||||
if (G_LIKELY (context->font_map != NULL))
|
||||
return context->font_map;
|
||||
|
||||
backend = clutter_context_get_backend (context);
|
||||
cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
font_map = pango_cairo_font_map_new ();
|
||||
font_renderer = clutter_pango_renderer_new (cogl_context);
|
||||
|
||||
resolution = clutter_backend_get_resolution (context->backend);
|
||||
pango_cairo_font_map_set_resolution (PANGO_CAIRO_FONT_MAP (font_map),
|
||||
resolution);
|
||||
|
||||
context->font_map = font_map;
|
||||
context->font_renderer = font_renderer;
|
||||
|
||||
return context->font_map;
|
||||
}
|
||||
|
||||
PangoRenderer *
|
||||
clutter_context_get_font_renderer (ClutterContext *context)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_CONTEXT (context), NULL);
|
||||
|
||||
return context->font_renderer;
|
||||
}
|
||||
#endif
|
||||
|
||||
ClutterTextDirection
|
||||
clutter_context_get_text_direction (ClutterContext *context)
|
||||
{
|
||||
ClutterContextPrivate *priv = clutter_context_get_instance_private (context);
|
||||
|
||||
return priv->text_direction;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_context_get_pipeline_cache: (skip)
|
||||
*/
|
||||
ClutterPipelineCache *
|
||||
clutter_context_get_pipeline_cache (ClutterContext *context)
|
||||
{
|
||||
ClutterContextPrivate *priv = clutter_context_get_instance_private (context);
|
||||
|
||||
return priv->pipeline_cache;
|
||||
}
|
||||
|
||||
ClutterColorManager *
|
||||
clutter_context_get_color_manager (ClutterContext *context)
|
||||
{
|
||||
ClutterContextPrivate *priv = clutter_context_get_instance_private (context);
|
||||
|
||||
return priv->color_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_get_accessibility_enabled:
|
||||
*
|
||||
* Returns whether Clutter has accessibility support enabled.
|
||||
*
|
||||
* Return value: %TRUE if Clutter has accessibility support enabled
|
||||
*/
|
||||
gboolean
|
||||
clutter_get_accessibility_enabled (void)
|
||||
{
|
||||
return clutter_enable_accessibility;
|
||||
}
|
||||
|
||||
ClutterStageManager *
|
||||
clutter_context_get_stage_manager (ClutterContext *context)
|
||||
{
|
||||
return context->stage_manager;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_context_get_show_fps (ClutterContext *context)
|
||||
{
|
||||
return context->show_fps;
|
||||
}
|
||||
|
||||
ClutterSettings *
|
||||
clutter_context_get_settings (ClutterContext *context)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_CONTEXT (context), NULL);
|
||||
|
||||
return context->settings;
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 OpenedHand
|
||||
* Copyright (C) 2023 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "clutter-backend.h"
|
||||
#include "clutter-settings.h"
|
||||
|
||||
typedef ClutterBackend * (* ClutterBackendConstructor) (ClutterContext *context,
|
||||
gpointer user_data);
|
||||
|
||||
#define CLUTTER_TYPE_CONTEXT (clutter_context_get_type ())
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_FINAL_TYPE (ClutterContext, clutter_context,
|
||||
CLUTTER, CONTEXT, GObject)
|
||||
|
||||
/**
|
||||
* clutter_context_new: (skip)
|
||||
*/
|
||||
ClutterContext * clutter_context_new (ClutterBackendConstructor backend_constructor,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
/**
|
||||
* clutter_context_destroy: (skip)
|
||||
*/
|
||||
CLUTTER_EXPORT
|
||||
void clutter_context_destroy (ClutterContext *context);
|
||||
|
||||
/**
|
||||
* clutter_context_get_backend:
|
||||
*
|
||||
* Returns: (transfer none): The %ClutterBackend
|
||||
*/
|
||||
CLUTTER_EXPORT
|
||||
ClutterBackend * clutter_context_get_backend (ClutterContext *context);
|
||||
|
||||
ClutterTextDirection clutter_context_get_text_direction (ClutterContext *context);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterPipelineCache * clutter_context_get_pipeline_cache (ClutterContext *clutter_context);
|
||||
|
||||
/**
|
||||
* clutter_context_get_color_manager:
|
||||
*
|
||||
* Returns: (transfer none): The %ClutterColorManager
|
||||
*/
|
||||
CLUTTER_EXPORT
|
||||
ClutterColorManager * clutter_context_get_color_manager (ClutterContext *context);
|
||||
|
||||
/**
|
||||
* clutter_context_get_settings:
|
||||
*
|
||||
* Returns: (transfer none): The %ClutterSettings
|
||||
*/
|
||||
CLUTTER_EXPORT
|
||||
ClutterSettings * clutter_context_get_settings (ClutterContext *context);
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007,2008,2009,2010,2011 Intel Corporation.
|
||||
* Copyright (C) 2020 Red Hat Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-damage-history.h"
|
||||
|
||||
#define DAMAGE_HISTORY_LENGTH 0x10
|
||||
|
||||
struct _ClutterDamageHistory
|
||||
{
|
||||
MtkRegion *damages[DAMAGE_HISTORY_LENGTH];
|
||||
int index;
|
||||
};
|
||||
|
||||
ClutterDamageHistory *
|
||||
clutter_damage_history_new (void)
|
||||
{
|
||||
ClutterDamageHistory *history;
|
||||
|
||||
history = g_new0 (ClutterDamageHistory, 1);
|
||||
|
||||
return history;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_damage_history_free (ClutterDamageHistory *history)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (history->damages); i++)
|
||||
g_clear_pointer (&history->damages[i], mtk_region_unref);
|
||||
|
||||
g_free (history);
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_damage_history_is_age_valid (ClutterDamageHistory *history,
|
||||
int age)
|
||||
{
|
||||
if (age >= DAMAGE_HISTORY_LENGTH ||
|
||||
age < 1)
|
||||
return FALSE;
|
||||
|
||||
if (!clutter_damage_history_lookup (history, age))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_damage_history_record (ClutterDamageHistory *history,
|
||||
const MtkRegion *damage)
|
||||
{
|
||||
g_clear_pointer (&history->damages[history->index], mtk_region_unref);
|
||||
history->damages[history->index] = mtk_region_copy (damage);
|
||||
}
|
||||
|
||||
static inline int
|
||||
step_damage_index (int current,
|
||||
int diff)
|
||||
{
|
||||
return (current + diff) & (DAMAGE_HISTORY_LENGTH - 1);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_damage_history_step (ClutterDamageHistory *history)
|
||||
{
|
||||
history->index = step_damage_index (history->index, 1);
|
||||
}
|
||||
|
||||
const MtkRegion *
|
||||
clutter_damage_history_lookup (ClutterDamageHistory *history,
|
||||
int age)
|
||||
{
|
||||
return history->damages[step_damage_index (history->index, -age)];
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007,2008,2009,2010,2011 Intel Corporation.
|
||||
* Copyright (C) 2020 Red Hat Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "clutter/clutter-macros.h"
|
||||
#include "mtk/mtk.h"
|
||||
|
||||
typedef struct _ClutterDamageHistory ClutterDamageHistory;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterDamageHistory * clutter_damage_history_new (void);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_damage_history_free (ClutterDamageHistory *history);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_damage_history_is_age_valid (ClutterDamageHistory *history,
|
||||
int age);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_damage_history_record (ClutterDamageHistory *history,
|
||||
const MtkRegion *damage);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_damage_history_step (ClutterDamageHistory *history);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
const MtkRegion * clutter_damage_history_lookup (ClutterDamageHistory *history,
|
||||
int age);
|
||||
@@ -1,51 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "clutter/clutter-main.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
|
||||
#define CLUTTER_HAS_DEBUG(type) ((clutter_debug_flags & CLUTTER_DEBUG_##type) != FALSE)
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
/* Try the GCC extension for valists in macros */
|
||||
#define CLUTTER_NOTE(type,x,a...) G_STMT_START { \
|
||||
if (G_UNLIKELY (CLUTTER_HAS_DEBUG (type))) { \
|
||||
_clutter_debug_message ("[" #type "]: " x, ##a); \
|
||||
} } G_STMT_END
|
||||
|
||||
#else /* !__GNUC__ */
|
||||
/* Try the C99 version; unfortunately, this does not allow us to pass
|
||||
* empty arguments to the macro, which means we have to
|
||||
* do an intemediate printf.
|
||||
*/
|
||||
#define CLUTTER_NOTE(type,...) G_STMT_START { \
|
||||
if (G_UNLIKELY (CLUTTER_HAS_DEBUG (type))) { \
|
||||
gchar *_fmt = g_strdup_printf (__VA_ARGS__); \
|
||||
_clutter_debug_message ("[" #type "]: %s", _fmt); \
|
||||
g_free (_fmt); \
|
||||
} } G_STMT_END
|
||||
#endif
|
||||
|
||||
#else /* !CLUTTER_ENABLE_DEBUG */
|
||||
|
||||
#define CLUTTER_NOTE(type,...) G_STMT_START { } G_STMT_END
|
||||
#define CLUTTER_HAS_DEBUG(type) FALSE
|
||||
|
||||
#endif /* CLUTTER_ENABLE_DEBUG */
|
||||
|
||||
extern guint clutter_debug_flags;
|
||||
extern guint clutter_pick_debug_flags;
|
||||
extern guint clutter_paint_debug_flags;
|
||||
extern int clutter_max_render_time_constant_us;
|
||||
|
||||
void _clutter_debug_messagev (const char *format,
|
||||
va_list var_args) G_GNUC_PRINTF (1, 0);
|
||||
void _clutter_debug_message (const char *format,
|
||||
...) G_GNUC_PRINTF (1, 2);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,821 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*
|
||||
* Based on the MxDeformTexture class, written by:
|
||||
* Chris Lord <chris@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterDeformEffect:
|
||||
*
|
||||
* A base class for effects deforming the geometry of an actor
|
||||
*
|
||||
* #ClutterDeformEffect is an abstract class providing all the plumbing
|
||||
* for creating effects that result in the deformation of an actor's
|
||||
* geometry.
|
||||
*
|
||||
* #ClutterDeformEffect uses offscreen buffers to render the contents of
|
||||
* a #ClutterActor and then the Cogl vertex buffers API to submit the
|
||||
* geometry to the GPU.
|
||||
*
|
||||
* ## Implementing ClutterDeformEffect
|
||||
*
|
||||
* Sub-classes of #ClutterDeformEffect should override the
|
||||
* [vfunc@Clutter.DeformEffect.deform_vertex] virtual function; this function
|
||||
* is called on every vertex that needs to be deformed by the effect.
|
||||
* Each passed vertex is an in-out parameter that initially contains the
|
||||
* position of the vertex and should be modified according to a specific
|
||||
* deformation algorithm.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
|
||||
#include "clutter/clutter-deform-effect.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-enum-types.h"
|
||||
#include "clutter/clutter-paint-node.h"
|
||||
#include "clutter/clutter-paint-nodes.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
#define DEFAULT_N_TILES 32
|
||||
|
||||
/**
|
||||
* ClutterVertexP3T2C4:
|
||||
* @x: The x component of a position attribute
|
||||
* @y: The y component of a position attribute
|
||||
* @z: The z component of a position attribute
|
||||
* @s: The s component of a texture coordinate attribute
|
||||
* @t: The t component of a texture coordinate attribute
|
||||
* @r: The red component of a color attribute
|
||||
* @b: The green component of a color attribute
|
||||
* @g: The blue component of a color attribute
|
||||
* @a: The alpha component of a color attribute
|
||||
*/
|
||||
typedef struct {
|
||||
float x, y, z;
|
||||
float s, t;
|
||||
uint8_t r, g, b, a;
|
||||
} ClutterVertexP3T2C4;
|
||||
|
||||
typedef struct _ClutterDeformEffectPrivate
|
||||
{
|
||||
CoglPipeline *back_pipeline;
|
||||
|
||||
gint x_tiles;
|
||||
gint y_tiles;
|
||||
|
||||
CoglAttributeBuffer *buffer;
|
||||
|
||||
CoglPrimitive *primitive;
|
||||
|
||||
CoglPrimitive *lines_primitive;
|
||||
|
||||
gint n_vertices;
|
||||
|
||||
gulong allocation_id;
|
||||
|
||||
guint is_dirty : 1;
|
||||
} ClutterDeformEffectPrivate;
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_X_TILES,
|
||||
PROP_Y_TILES,
|
||||
|
||||
PROP_BACK_PIPELINE,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterDeformEffect,
|
||||
clutter_deform_effect,
|
||||
CLUTTER_TYPE_OFFSCREEN_EFFECT)
|
||||
|
||||
static void
|
||||
clutter_deform_effect_real_deform_vertex (ClutterDeformEffect *effect,
|
||||
gfloat width,
|
||||
gfloat height,
|
||||
ClutterTextureVertex *vertex)
|
||||
{
|
||||
g_warning ("%s: Deformation effect of type '%s' does not implement "
|
||||
"the required ClutterDeformEffect::deform_vertex virtual "
|
||||
"function.",
|
||||
G_STRLOC,
|
||||
G_OBJECT_TYPE_NAME (effect));
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_deform_effect_deform_vertex (ClutterDeformEffect *effect,
|
||||
gfloat width,
|
||||
gfloat height,
|
||||
ClutterTextureVertex *vertex)
|
||||
{
|
||||
CLUTTER_DEFORM_EFFECT_GET_CLASS (effect)->deform_vertex (effect,
|
||||
width, height,
|
||||
vertex);
|
||||
}
|
||||
|
||||
static void
|
||||
vbo_invalidate (ClutterActor *actor,
|
||||
GParamSpec *pspec,
|
||||
ClutterDeformEffect *effect)
|
||||
{
|
||||
ClutterDeformEffectPrivate *priv =
|
||||
clutter_deform_effect_get_instance_private (effect);
|
||||
|
||||
priv->is_dirty = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_deform_effect_set_actor (ClutterActorMeta *meta,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterDeformEffect *effect = CLUTTER_DEFORM_EFFECT (meta);
|
||||
ClutterDeformEffectPrivate *priv =
|
||||
clutter_deform_effect_get_instance_private (effect);
|
||||
|
||||
if (priv->allocation_id != 0)
|
||||
{
|
||||
ClutterActor *old_actor = clutter_actor_meta_get_actor (meta);
|
||||
|
||||
if (old_actor != NULL)
|
||||
g_clear_signal_handler (&priv->allocation_id, old_actor);
|
||||
|
||||
priv->allocation_id = 0;
|
||||
}
|
||||
|
||||
/* we need to invalidate the VBO whenever the allocation of the actor
|
||||
* changes
|
||||
*/
|
||||
if (actor != NULL)
|
||||
priv->allocation_id = g_signal_connect (actor, "notify::allocation",
|
||||
G_CALLBACK (vbo_invalidate),
|
||||
meta);
|
||||
|
||||
priv->is_dirty = TRUE;
|
||||
|
||||
CLUTTER_ACTOR_META_CLASS (clutter_deform_effect_parent_class)->set_actor (meta, actor);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
ClutterDeformEffect *self = CLUTTER_DEFORM_EFFECT (effect);
|
||||
ClutterDeformEffectPrivate *priv =
|
||||
clutter_deform_effect_get_instance_private (self);
|
||||
CoglPipeline *pipeline;
|
||||
CoglDepthState depth_state;
|
||||
|
||||
if (priv->is_dirty)
|
||||
{
|
||||
gboolean mapped_buffer;
|
||||
ClutterVertexP3T2C4 *verts;
|
||||
ClutterActor *actor;
|
||||
gfloat width, height;
|
||||
guint opacity;
|
||||
gint i, j;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
|
||||
opacity = clutter_actor_get_paint_opacity (actor);
|
||||
|
||||
/* if we don't have a target size, fall back to the actor's
|
||||
* allocation, though wrong it might be
|
||||
*/
|
||||
if (!clutter_offscreen_effect_get_target_size (effect, &width, &height))
|
||||
clutter_actor_get_size (actor, &width, &height);
|
||||
|
||||
/* XXX ideally, the sub-classes should tell us what they
|
||||
* changed in the texture vertices; we then would be able to
|
||||
* avoid resubmitting the same data, if it did not change. for
|
||||
* the time being, we resubmit everything
|
||||
*/
|
||||
verts = cogl_buffer_map (COGL_BUFFER (priv->buffer),
|
||||
COGL_BUFFER_ACCESS_WRITE,
|
||||
COGL_BUFFER_MAP_HINT_DISCARD);
|
||||
|
||||
/* If the map failed then we'll resort to allocating a temporary
|
||||
buffer */
|
||||
if (verts == NULL)
|
||||
{
|
||||
mapped_buffer = FALSE;
|
||||
verts = g_malloc (sizeof (*verts) * priv->n_vertices);
|
||||
}
|
||||
else
|
||||
mapped_buffer = TRUE;
|
||||
|
||||
for (i = 0; i < priv->y_tiles + 1; i++)
|
||||
{
|
||||
for (j = 0; j < priv->x_tiles + 1; j++)
|
||||
{
|
||||
ClutterVertexP3T2C4 *vertex_out;
|
||||
ClutterTextureVertex vertex;
|
||||
|
||||
/* CoglTextureVertex isn't an ideal structure to use for
|
||||
this because it contains a CoglColor. The internal
|
||||
layout of CoglColor is mean to be private so Clutter
|
||||
can not pass a pointer to it as a vertex
|
||||
attribute. Also it contains padding so we end up
|
||||
storing more data in the vertex buffer than we need
|
||||
to. Instead we let the application modify a dummy
|
||||
vertex and then copy the details back out to a more
|
||||
well-defined struct */
|
||||
|
||||
vertex.tx = (float) j / priv->x_tiles;
|
||||
vertex.ty = (float) i / priv->y_tiles;
|
||||
|
||||
vertex.x = width * vertex.tx;
|
||||
vertex.y = height * vertex.ty;
|
||||
vertex.z = 0.0f;
|
||||
|
||||
cogl_color_init_from_4f (&vertex.color,
|
||||
1.0f, 1.0f, 1.0f, opacity / 255.0f);
|
||||
|
||||
clutter_deform_effect_deform_vertex (self,
|
||||
width, height,
|
||||
&vertex);
|
||||
|
||||
vertex_out = verts + i * (priv->x_tiles + 1) + j;
|
||||
|
||||
vertex_out->x = vertex.x;
|
||||
vertex_out->y = vertex.y;
|
||||
vertex_out->z = vertex.z;
|
||||
vertex_out->s = vertex.tx;
|
||||
vertex_out->t = vertex.ty;
|
||||
vertex_out->r = (uint8_t) (cogl_color_get_red (&vertex.color) * 255.0f);
|
||||
vertex_out->g = (uint8_t) (cogl_color_get_green (&vertex.color) * 255.0f);
|
||||
vertex_out->b = (uint8_t) (cogl_color_get_blue (&vertex.color) * 255.0f);
|
||||
vertex_out->a = (uint8_t) (cogl_color_get_alpha (&vertex.color) * 255.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (mapped_buffer)
|
||||
cogl_buffer_unmap (COGL_BUFFER (priv->buffer));
|
||||
else
|
||||
{
|
||||
cogl_buffer_set_data (COGL_BUFFER (priv->buffer),
|
||||
0, /* offset */
|
||||
verts,
|
||||
sizeof (*verts) * priv->n_vertices);
|
||||
g_free (verts);
|
||||
}
|
||||
|
||||
priv->is_dirty = FALSE;
|
||||
}
|
||||
|
||||
pipeline = clutter_offscreen_effect_get_pipeline (effect);
|
||||
|
||||
/* enable depth testing */
|
||||
cogl_depth_state_init (&depth_state);
|
||||
cogl_depth_state_set_test_enabled (&depth_state, TRUE);
|
||||
cogl_depth_state_set_test_function (&depth_state, COGL_DEPTH_TEST_FUNCTION_LEQUAL);
|
||||
cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL);
|
||||
|
||||
/* enable backface culling if we have a back pipeline */
|
||||
if (priv->back_pipeline != NULL)
|
||||
cogl_pipeline_set_cull_face_mode (pipeline,
|
||||
COGL_PIPELINE_CULL_FACE_MODE_BACK);
|
||||
|
||||
/* draw the front */
|
||||
if (pipeline != NULL)
|
||||
{
|
||||
ClutterPaintNode *front_node;
|
||||
|
||||
front_node = clutter_pipeline_node_new (pipeline);
|
||||
clutter_paint_node_set_static_name (front_node,
|
||||
"ClutterDeformEffect (front)");
|
||||
clutter_paint_node_add_child (node, front_node);
|
||||
clutter_paint_node_add_primitive (front_node, priv->primitive);
|
||||
clutter_paint_node_unref (front_node);
|
||||
}
|
||||
|
||||
/* draw the back */
|
||||
if (priv->back_pipeline != NULL)
|
||||
{
|
||||
ClutterPaintNode *back_node;
|
||||
CoglPipeline *back_pipeline;
|
||||
|
||||
/* We probably shouldn't be modifying the user's pipeline so
|
||||
instead we make a temporary copy */
|
||||
back_pipeline = cogl_pipeline_copy (priv->back_pipeline);
|
||||
cogl_pipeline_set_depth_state (back_pipeline, &depth_state, NULL);
|
||||
cogl_pipeline_set_cull_face_mode (back_pipeline,
|
||||
COGL_PIPELINE_CULL_FACE_MODE_FRONT);
|
||||
|
||||
|
||||
back_node = clutter_pipeline_node_new (back_pipeline);
|
||||
clutter_paint_node_set_static_name (back_node,
|
||||
"ClutterDeformEffect (back)");
|
||||
clutter_paint_node_add_child (node, back_node);
|
||||
clutter_paint_node_add_primitive (back_node, priv->primitive);
|
||||
|
||||
clutter_paint_node_unref (back_node);
|
||||
g_object_unref (back_pipeline);
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (priv->lines_primitive != NULL))
|
||||
{
|
||||
static CoglColor red = COGL_COLOR_INIT (255, 0, 0, 255);
|
||||
ClutterPaintNode *lines_node;
|
||||
|
||||
lines_node = clutter_color_node_new (&red);
|
||||
clutter_paint_node_set_static_name (lines_node,
|
||||
"ClutterDeformEffect (lines)");
|
||||
clutter_paint_node_add_child (node, lines_node);
|
||||
clutter_paint_node_add_primitive (lines_node, priv->lines_primitive);
|
||||
clutter_paint_node_unref (lines_node);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
clutter_deform_effect_free_arrays (ClutterDeformEffect *self)
|
||||
{
|
||||
ClutterDeformEffectPrivate *priv =
|
||||
clutter_deform_effect_get_instance_private (self);
|
||||
|
||||
g_clear_object (&priv->buffer);
|
||||
g_clear_object (&priv->primitive);
|
||||
g_clear_object (&priv->lines_primitive);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_deform_effect_init_arrays (ClutterDeformEffect *self)
|
||||
{
|
||||
ClutterDeformEffectPrivate *priv =
|
||||
clutter_deform_effect_get_instance_private (self);
|
||||
gint x, y, direction, n_indices;
|
||||
CoglAttribute *attributes[3];
|
||||
guint16 *static_indices;
|
||||
ClutterContext *context = _clutter_context_get_default ();
|
||||
ClutterBackend *backend = clutter_context_get_backend (context);
|
||||
CoglContext *cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
CoglIndices *indices;
|
||||
guint16 *idx;
|
||||
int i;
|
||||
|
||||
clutter_deform_effect_free_arrays (self);
|
||||
|
||||
n_indices = ((2 + 2 * priv->x_tiles)
|
||||
* priv->y_tiles
|
||||
+ (priv->y_tiles - 1));
|
||||
|
||||
static_indices = g_new (guint16, n_indices);
|
||||
|
||||
#define MESH_INDEX(x,y) ((y) * (priv->x_tiles + 1) + (x))
|
||||
|
||||
/* compute all the triangles from the various tiles */
|
||||
direction = 1;
|
||||
|
||||
idx = static_indices;
|
||||
idx[0] = MESH_INDEX (0, 0);
|
||||
idx[1] = MESH_INDEX (0, 1);
|
||||
idx += 2;
|
||||
|
||||
for (y = 0; y < priv->y_tiles; y++)
|
||||
{
|
||||
for (x = 0; x < priv->x_tiles; x++)
|
||||
{
|
||||
if (direction)
|
||||
{
|
||||
idx[0] = MESH_INDEX (x + 1, y);
|
||||
idx[1] = MESH_INDEX (x + 1, y + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
idx[0] = MESH_INDEX (priv->x_tiles - x - 1, y);
|
||||
idx[1] = MESH_INDEX (priv->x_tiles - x - 1, y + 1);
|
||||
}
|
||||
|
||||
idx += 2;
|
||||
}
|
||||
|
||||
if (y == (priv->y_tiles - 1))
|
||||
break;
|
||||
|
||||
if (direction)
|
||||
{
|
||||
idx[0] = MESH_INDEX (priv->x_tiles, y + 1);
|
||||
idx[1] = MESH_INDEX (priv->x_tiles, y + 1);
|
||||
idx[2] = MESH_INDEX (priv->x_tiles, y + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
idx[0] = MESH_INDEX (0, y + 1);
|
||||
idx[1] = MESH_INDEX (0, y + 1);
|
||||
idx[2] = MESH_INDEX (0, y + 2);
|
||||
}
|
||||
|
||||
idx += 3;
|
||||
|
||||
direction = !direction;
|
||||
}
|
||||
|
||||
#undef MESH_INDEX
|
||||
|
||||
indices = cogl_indices_new (cogl_context,
|
||||
COGL_INDICES_TYPE_UNSIGNED_SHORT,
|
||||
static_indices,
|
||||
n_indices);
|
||||
|
||||
g_free (static_indices);
|
||||
|
||||
priv->n_vertices = (priv->x_tiles + 1) * (priv->y_tiles + 1);
|
||||
|
||||
priv->buffer =
|
||||
cogl_attribute_buffer_new (cogl_context,
|
||||
sizeof (ClutterVertexP3T2C4) *
|
||||
priv->n_vertices,
|
||||
NULL);
|
||||
|
||||
/* The application is expected to continuously modify the vertices
|
||||
so we should give a hint to Cogl about that */
|
||||
cogl_buffer_set_update_hint (COGL_BUFFER (priv->buffer),
|
||||
COGL_BUFFER_UPDATE_HINT_DYNAMIC);
|
||||
|
||||
attributes[0] = cogl_attribute_new (priv->buffer,
|
||||
"cogl_position_in",
|
||||
sizeof (ClutterVertexP3T2C4),
|
||||
G_STRUCT_OFFSET (ClutterVertexP3T2C4, x),
|
||||
3, /* n_components */
|
||||
COGL_ATTRIBUTE_TYPE_FLOAT);
|
||||
attributes[1] = cogl_attribute_new (priv->buffer,
|
||||
"cogl_tex_coord0_in",
|
||||
sizeof (ClutterVertexP3T2C4),
|
||||
G_STRUCT_OFFSET (ClutterVertexP3T2C4, s),
|
||||
2, /* n_components */
|
||||
COGL_ATTRIBUTE_TYPE_FLOAT);
|
||||
attributes[2] = cogl_attribute_new (priv->buffer,
|
||||
"cogl_color_in",
|
||||
sizeof (ClutterVertexP3T2C4),
|
||||
G_STRUCT_OFFSET (ClutterVertexP3T2C4, r),
|
||||
4, /* n_components */
|
||||
COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE);
|
||||
|
||||
priv->primitive =
|
||||
cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLE_STRIP,
|
||||
priv->n_vertices,
|
||||
attributes,
|
||||
3 /* n_attributes */);
|
||||
cogl_primitive_set_indices (priv->primitive,
|
||||
indices,
|
||||
n_indices);
|
||||
|
||||
if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DEFORM_TILES))
|
||||
{
|
||||
priv->lines_primitive =
|
||||
cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_LINE_STRIP,
|
||||
priv->n_vertices,
|
||||
attributes,
|
||||
2 /* n_attributes */);
|
||||
cogl_primitive_set_indices (priv->lines_primitive,
|
||||
indices,
|
||||
n_indices);
|
||||
}
|
||||
|
||||
g_object_unref (indices);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
g_object_unref (attributes[i]);
|
||||
|
||||
priv->is_dirty = TRUE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
clutter_deform_effect_free_back_pipeline (ClutterDeformEffect *self)
|
||||
{
|
||||
ClutterDeformEffectPrivate *priv =
|
||||
clutter_deform_effect_get_instance_private (self);
|
||||
|
||||
g_clear_object (&priv->back_pipeline);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_deform_effect_finalize (GObject *gobject)
|
||||
{
|
||||
ClutterDeformEffect *self = CLUTTER_DEFORM_EFFECT (gobject);
|
||||
|
||||
clutter_deform_effect_free_arrays (self);
|
||||
clutter_deform_effect_free_back_pipeline (self);
|
||||
|
||||
G_OBJECT_CLASS (clutter_deform_effect_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_deform_effect_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterDeformEffect *self = CLUTTER_DEFORM_EFFECT (gobject);
|
||||
ClutterDeformEffectPrivate *priv =
|
||||
clutter_deform_effect_get_instance_private (self);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_X_TILES:
|
||||
clutter_deform_effect_set_n_tiles (self, g_value_get_uint (value),
|
||||
priv->y_tiles);
|
||||
break;
|
||||
|
||||
case PROP_Y_TILES:
|
||||
clutter_deform_effect_set_n_tiles (self, priv->x_tiles,
|
||||
g_value_get_uint (value));
|
||||
break;
|
||||
|
||||
case PROP_BACK_PIPELINE:
|
||||
clutter_deform_effect_set_back_pipeline (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_deform_effect_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterDeformEffect *effect = CLUTTER_DEFORM_EFFECT (gobject);
|
||||
ClutterDeformEffectPrivate *priv =
|
||||
clutter_deform_effect_get_instance_private (effect);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_X_TILES:
|
||||
g_value_set_uint (value, priv->x_tiles);
|
||||
break;
|
||||
|
||||
case PROP_Y_TILES:
|
||||
g_value_set_uint (value, priv->y_tiles);
|
||||
break;
|
||||
|
||||
case PROP_BACK_PIPELINE:
|
||||
g_value_set_object (value, priv->back_pipeline);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_deform_effect_class_init (ClutterDeformEffectClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
|
||||
ClutterOffscreenEffectClass *offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
||||
|
||||
klass->deform_vertex = clutter_deform_effect_real_deform_vertex;
|
||||
|
||||
/**
|
||||
* ClutterDeformEffect:x-tiles:
|
||||
*
|
||||
* The number of horizontal tiles. The bigger the number, the
|
||||
* smaller the tiles
|
||||
*/
|
||||
obj_props[PROP_X_TILES] =
|
||||
g_param_spec_uint ("x-tiles", NULL, NULL,
|
||||
1, G_MAXUINT,
|
||||
DEFAULT_N_TILES,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterDeformEffect:y-tiles:
|
||||
*
|
||||
* The number of vertical tiles. The bigger the number, the
|
||||
* smaller the tiles
|
||||
*/
|
||||
obj_props[PROP_Y_TILES] =
|
||||
g_param_spec_uint ("y-tiles", NULL, NULL,
|
||||
1, G_MAXUINT,
|
||||
DEFAULT_N_TILES,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterDeformEffect:back-pipeline:
|
||||
*
|
||||
* A pipeline to be used when painting the back of the actor
|
||||
* to which this effect has been applied
|
||||
*
|
||||
* By default, no pipeline will be used
|
||||
*/
|
||||
obj_props[PROP_BACK_PIPELINE] =
|
||||
g_param_spec_object ("back-pipeline", NULL, NULL,
|
||||
COGL_TYPE_PIPELINE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
gobject_class->finalize = clutter_deform_effect_finalize;
|
||||
gobject_class->set_property = clutter_deform_effect_set_property;
|
||||
gobject_class->get_property = clutter_deform_effect_get_property;
|
||||
g_object_class_install_properties (gobject_class,
|
||||
PROP_LAST,
|
||||
obj_props);
|
||||
|
||||
meta_class->set_actor = clutter_deform_effect_set_actor;
|
||||
|
||||
offscreen_class->paint_target = clutter_deform_effect_paint_target;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_deform_effect_init (ClutterDeformEffect *self)
|
||||
{
|
||||
ClutterDeformEffectPrivate *priv =
|
||||
clutter_deform_effect_get_instance_private (self);
|
||||
|
||||
priv->x_tiles = priv->y_tiles = DEFAULT_N_TILES;
|
||||
priv->back_pipeline = NULL;
|
||||
|
||||
clutter_deform_effect_init_arrays (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_deform_effect_set_back_pipeline:
|
||||
* @effect: a #ClutterDeformEffect
|
||||
* @pipeline: (allow-none): A #CoglPipeline
|
||||
*
|
||||
* Sets the pipeline that should be used when drawing the back face
|
||||
* of the actor during a deformation
|
||||
*
|
||||
* The #ClutterDeformEffect will take a reference on the pipeline's
|
||||
* handle
|
||||
*/
|
||||
void
|
||||
clutter_deform_effect_set_back_pipeline (ClutterDeformEffect *effect,
|
||||
CoglPipeline *pipeline)
|
||||
{
|
||||
ClutterDeformEffectPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect));
|
||||
g_return_if_fail (pipeline == NULL || COGL_IS_PIPELINE (pipeline));
|
||||
|
||||
priv = clutter_deform_effect_get_instance_private (effect);
|
||||
|
||||
clutter_deform_effect_free_back_pipeline (effect);
|
||||
|
||||
priv->back_pipeline = pipeline;
|
||||
if (priv->back_pipeline != NULL)
|
||||
g_object_ref (priv->back_pipeline);
|
||||
|
||||
clutter_deform_effect_invalidate (effect);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_deform_effect_get_back_pipeline:
|
||||
* @effect: a #ClutterDeformEffect
|
||||
*
|
||||
* Retrieves the back pipeline used by @effect
|
||||
*
|
||||
* Return value: (transfer none) (nullable): A #CoglPipeline.
|
||||
*/
|
||||
CoglPipeline*
|
||||
clutter_deform_effect_get_back_pipeline (ClutterDeformEffect *effect)
|
||||
{
|
||||
ClutterDeformEffectPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect), NULL);
|
||||
|
||||
priv = clutter_deform_effect_get_instance_private (effect);
|
||||
return priv->back_pipeline;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_deform_effect_set_n_tiles:
|
||||
* @effect: a #ClutterDeformEffect
|
||||
* @x_tiles: number of horizontal tiles
|
||||
* @y_tiles: number of vertical tiles
|
||||
*
|
||||
* Sets the number of horizontal and vertical tiles to be used
|
||||
* when applying the effect
|
||||
*
|
||||
* More tiles allow a finer grained deformation at the expenses
|
||||
* of computation
|
||||
*/
|
||||
void
|
||||
clutter_deform_effect_set_n_tiles (ClutterDeformEffect *effect,
|
||||
guint x_tiles,
|
||||
guint y_tiles)
|
||||
{
|
||||
ClutterDeformEffectPrivate *priv;
|
||||
gboolean tiles_changed = FALSE;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect));
|
||||
g_return_if_fail (x_tiles > 0 && y_tiles > 0);
|
||||
|
||||
priv = clutter_deform_effect_get_instance_private (effect);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (effect));
|
||||
|
||||
if (priv->x_tiles != x_tiles)
|
||||
{
|
||||
priv->x_tiles = x_tiles;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_X_TILES]);
|
||||
|
||||
tiles_changed = TRUE;
|
||||
}
|
||||
|
||||
if (priv->y_tiles != y_tiles)
|
||||
{
|
||||
priv->y_tiles = y_tiles;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_Y_TILES]);
|
||||
|
||||
tiles_changed = TRUE;
|
||||
}
|
||||
|
||||
if (tiles_changed)
|
||||
{
|
||||
clutter_deform_effect_init_arrays (effect);
|
||||
clutter_deform_effect_invalidate (effect);
|
||||
}
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (effect));
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_deform_effect_get_n_tiles:
|
||||
* @effect: a #ClutterDeformEffect
|
||||
* @x_tiles: (out): return location for the number of horizontal tiles,
|
||||
* or %NULL
|
||||
* @y_tiles: (out): return location for the number of vertical tiles,
|
||||
* or %NULL
|
||||
*
|
||||
* Retrieves the number of horizontal and vertical tiles used to sub-divide
|
||||
* the actor's geometry during the effect
|
||||
*/
|
||||
void
|
||||
clutter_deform_effect_get_n_tiles (ClutterDeformEffect *effect,
|
||||
guint *x_tiles,
|
||||
guint *y_tiles)
|
||||
{
|
||||
ClutterDeformEffectPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect));
|
||||
|
||||
priv = clutter_deform_effect_get_instance_private (effect);
|
||||
if (x_tiles != NULL)
|
||||
*x_tiles = priv->x_tiles;
|
||||
|
||||
if (y_tiles != NULL)
|
||||
*y_tiles = priv->y_tiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_deform_effect_invalidate:
|
||||
* @effect: a #ClutterDeformEffect
|
||||
*
|
||||
* Invalidates the `effect`'s vertices and, if it is associated
|
||||
* to an actor, it will queue a redraw
|
||||
*/
|
||||
void
|
||||
clutter_deform_effect_invalidate (ClutterDeformEffect *effect)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
ClutterDeformEffectPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect));
|
||||
|
||||
priv = clutter_deform_effect_get_instance_private (effect);
|
||||
if (priv->is_dirty)
|
||||
return;
|
||||
|
||||
priv->is_dirty = TRUE;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
|
||||
if (actor != NULL)
|
||||
clutter_effect_queue_repaint (CLUTTER_EFFECT (effect));
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
#include "clutter/clutter-offscreen-effect.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_DEFORM_EFFECT (clutter_deform_effect_get_type ())
|
||||
|
||||
|
||||
/**
|
||||
* ClutterTextureVertex:
|
||||
* @x: Model x-coordinate
|
||||
* @y: Model y-coordinate
|
||||
* @z: Model z-coordinate
|
||||
* @tx: Texture x-coordinate
|
||||
* @ty: Texture y-coordinate
|
||||
* @color: The color to use at this vertex. This is ignored if
|
||||
* use_color is %FALSE when calling cogl_polygon()
|
||||
*
|
||||
* Used to specify vertex information when calling cogl_polygon()
|
||||
*/
|
||||
typedef struct _ClutterTextureVertex
|
||||
{
|
||||
float x, y, z;
|
||||
float tx, ty;
|
||||
|
||||
CoglColor color;
|
||||
} ClutterTextureVertex;
|
||||
|
||||
#ifndef __GI_SCANNER__
|
||||
G_STATIC_ASSERT (sizeof (ClutterTextureVertex) == 24);
|
||||
#endif
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterDeformEffect,
|
||||
clutter_deform_effect,
|
||||
CLUTTER,
|
||||
DEFORM_EFFECT,
|
||||
ClutterOffscreenEffect)
|
||||
|
||||
/**
|
||||
* ClutterDeformEffectClass:
|
||||
* @deform_vertex: virtual function; sub-classes should override this
|
||||
* function to compute the deformation of each vertex
|
||||
*
|
||||
* The #ClutterDeformEffectClass structure contains
|
||||
* only private data
|
||||
*/
|
||||
struct _ClutterDeformEffectClass
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterOffscreenEffectClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
void (* deform_vertex) (ClutterDeformEffect *effect,
|
||||
gfloat width,
|
||||
gfloat height,
|
||||
ClutterTextureVertex *vertex);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_deform_effect_set_back_pipeline (ClutterDeformEffect *effect,
|
||||
CoglPipeline *pipeline);
|
||||
CLUTTER_EXPORT
|
||||
CoglPipeline* clutter_deform_effect_get_back_pipeline (ClutterDeformEffect *effect);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_deform_effect_set_n_tiles (ClutterDeformEffect *effect,
|
||||
guint x_tiles,
|
||||
guint y_tiles);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_deform_effect_get_n_tiles (ClutterDeformEffect *effect,
|
||||
guint *x_tiles,
|
||||
guint *y_tiles);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_deform_effect_invalidate (ClutterDeformEffect *effect);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,308 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterDesaturateEffect:
|
||||
*
|
||||
* A desaturation effect
|
||||
*
|
||||
* #ClutterDesaturateEffect is a sub-class of #ClutterEffect that
|
||||
* desaturates the color of an actor and its contents. The strength
|
||||
* of the desaturation effect is controllable and animatable through
|
||||
* the #ClutterDesaturateEffect:factor property.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "clutter/clutter-desaturate-effect.h"
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-enum-types.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
typedef struct _ClutterDesaturateEffectPrivate
|
||||
{
|
||||
/* the desaturation factor, also known as "strength" */
|
||||
gdouble factor;
|
||||
|
||||
gint factor_uniform;
|
||||
|
||||
gint tex_width;
|
||||
gint tex_height;
|
||||
|
||||
CoglPipeline *pipeline;
|
||||
} ClutterDesaturateEffectPrivate;
|
||||
|
||||
|
||||
/* the magic gray vec3 has been taken from the NTSC conversion weights
|
||||
* as defined by:
|
||||
*
|
||||
* "OpenGL Superbible, 4th edition"
|
||||
* -- Richard S. Wright Jr, Benjamin Lipchak, Nicholas Haemel
|
||||
* Addison-Wesley
|
||||
*/
|
||||
static const gchar *desaturate_glsl_declarations =
|
||||
"uniform float factor;\n"
|
||||
"\n"
|
||||
"vec3 desaturate (const vec3 color, const float desaturation)\n"
|
||||
"{\n"
|
||||
" const vec3 gray_conv = vec3 (0.299, 0.587, 0.114);\n"
|
||||
" vec3 gray = vec3 (dot (gray_conv, color));\n"
|
||||
" return vec3 (mix (color.rgb, gray, desaturation));\n"
|
||||
"}\n";
|
||||
|
||||
static const gchar *desaturate_glsl_source =
|
||||
" cogl_color_out.rgb = desaturate (cogl_color_out.rgb, factor);\n";
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_FACTOR,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterDesaturateEffect,
|
||||
clutter_desaturate_effect,
|
||||
CLUTTER_TYPE_OFFSCREEN_EFFECT);
|
||||
|
||||
static CoglPipeline *
|
||||
clutter_desaturate_effect_create_pipeline (ClutterOffscreenEffect *effect,
|
||||
CoglTexture *texture)
|
||||
{
|
||||
ClutterDesaturateEffect *desaturate_effect =
|
||||
CLUTTER_DESATURATE_EFFECT (effect);
|
||||
ClutterDesaturateEffectPrivate *priv =
|
||||
clutter_desaturate_effect_get_instance_private (desaturate_effect);
|
||||
|
||||
cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture);
|
||||
|
||||
return g_object_ref (priv->pipeline);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_desaturate_effect_dispose (GObject *gobject)
|
||||
{
|
||||
ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (gobject);
|
||||
ClutterDesaturateEffectPrivate *priv =
|
||||
clutter_desaturate_effect_get_instance_private (self);
|
||||
|
||||
g_clear_object (&priv->pipeline);
|
||||
|
||||
G_OBJECT_CLASS (clutter_desaturate_effect_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_desaturate_effect_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterDesaturateEffect *effect = CLUTTER_DESATURATE_EFFECT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FACTOR:
|
||||
clutter_desaturate_effect_set_factor (effect,
|
||||
g_value_get_double (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_desaturate_effect_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterDesaturateEffect *effect = CLUTTER_DESATURATE_EFFECT (gobject);
|
||||
ClutterDesaturateEffectPrivate *priv =
|
||||
clutter_desaturate_effect_get_instance_private (effect);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FACTOR:
|
||||
g_value_set_double (value, priv->factor);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_factor_uniform (ClutterDesaturateEffect *self)
|
||||
{
|
||||
ClutterDesaturateEffectPrivate *priv =
|
||||
clutter_desaturate_effect_get_instance_private (self);
|
||||
|
||||
if (priv->factor_uniform > -1)
|
||||
cogl_pipeline_set_uniform_1f (priv->pipeline,
|
||||
priv->factor_uniform,
|
||||
(float) priv->factor);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_desaturate_effect_class_init (ClutterDesaturateEffectClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterOffscreenEffectClass *offscreen_class;
|
||||
|
||||
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
||||
offscreen_class->create_pipeline = clutter_desaturate_effect_create_pipeline;
|
||||
|
||||
/**
|
||||
* ClutterDesaturateEffect:factor:
|
||||
*
|
||||
* The desaturation factor, between 0.0 (no desaturation) and 1.0 (full
|
||||
* desaturation).
|
||||
*/
|
||||
obj_props[PROP_FACTOR] =
|
||||
g_param_spec_double ("factor", NULL, NULL,
|
||||
0.0, 1.0,
|
||||
1.0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
gobject_class->dispose = clutter_desaturate_effect_dispose;
|
||||
gobject_class->set_property = clutter_desaturate_effect_set_property;
|
||||
gobject_class->get_property = clutter_desaturate_effect_get_property;
|
||||
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_desaturate_effect_init (ClutterDesaturateEffect *self)
|
||||
{
|
||||
ClutterDesaturateEffectClass *klass = CLUTTER_DESATURATE_EFFECT_GET_CLASS (self);
|
||||
ClutterDesaturateEffectPrivate *priv =
|
||||
clutter_desaturate_effect_get_instance_private (self);
|
||||
|
||||
if (G_UNLIKELY (klass->base_pipeline == NULL))
|
||||
{
|
||||
ClutterContext *context = _clutter_context_get_default ();
|
||||
ClutterBackend *backend = clutter_context_get_backend (context);
|
||||
CoglContext *cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
CoglSnippet *snippet;
|
||||
|
||||
klass->base_pipeline = cogl_pipeline_new (cogl_context);
|
||||
cogl_pipeline_set_static_name (klass->base_pipeline, "ClutterDesaturate");
|
||||
|
||||
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
|
||||
desaturate_glsl_declarations,
|
||||
desaturate_glsl_source);
|
||||
cogl_pipeline_add_snippet (klass->base_pipeline, snippet);
|
||||
g_object_unref (snippet);
|
||||
|
||||
cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0);
|
||||
}
|
||||
|
||||
priv->pipeline = cogl_pipeline_copy (klass->base_pipeline);
|
||||
|
||||
priv->factor_uniform =
|
||||
cogl_pipeline_get_uniform_location (priv->pipeline, "factor");
|
||||
|
||||
priv->factor = 1.0;
|
||||
|
||||
update_factor_uniform (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_desaturate_effect_new:
|
||||
* @factor: the desaturation factor, between 0.0 and 1.0
|
||||
*
|
||||
* Creates a new #ClutterDesaturateEffect to be used with
|
||||
* [method@Clutter.Actor.add_effect]
|
||||
*
|
||||
* Return value: the newly created #ClutterDesaturateEffect or %NULL
|
||||
*/
|
||||
ClutterEffect *
|
||||
clutter_desaturate_effect_new (gdouble factor)
|
||||
{
|
||||
g_return_val_if_fail (factor >= 0.0 && factor <= 1.0, NULL);
|
||||
|
||||
return g_object_new (CLUTTER_TYPE_DESATURATE_EFFECT,
|
||||
"factor", factor,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_desaturate_effect_set_factor:
|
||||
* @effect: a #ClutterDesaturateEffect
|
||||
* @factor: the desaturation factor, between 0.0 and 1.0
|
||||
*
|
||||
* Sets the desaturation factor for @effect, with 0.0 being "do not desaturate"
|
||||
* and 1.0 being "fully desaturate"
|
||||
*/
|
||||
void
|
||||
clutter_desaturate_effect_set_factor (ClutterDesaturateEffect *effect,
|
||||
double factor)
|
||||
{
|
||||
ClutterDesaturateEffectPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DESATURATE_EFFECT (effect));
|
||||
g_return_if_fail (factor >= 0.0 && factor <= 1.0);
|
||||
|
||||
priv = clutter_desaturate_effect_get_instance_private (effect);
|
||||
if (fabs (priv->factor - factor) >= 0.00001)
|
||||
{
|
||||
priv->factor = factor;
|
||||
update_factor_uniform (effect);
|
||||
|
||||
clutter_effect_queue_repaint (CLUTTER_EFFECT (effect));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_FACTOR]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_desaturate_effect_get_factor:
|
||||
* @effect: a #ClutterDesaturateEffect
|
||||
*
|
||||
* Retrieves the desaturation factor of @effect
|
||||
*
|
||||
* Return value: the desaturation factor
|
||||
*/
|
||||
gdouble
|
||||
clutter_desaturate_effect_get_factor (ClutterDesaturateEffect *effect)
|
||||
{
|
||||
ClutterDesaturateEffectPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_DESATURATE_EFFECT (effect), 0.0);
|
||||
|
||||
priv = clutter_desaturate_effect_get_instance_private (effect);
|
||||
return priv->factor;
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-effect.h"
|
||||
#include "clutter/clutter-offscreen-effect.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_DESATURATE_EFFECT (clutter_desaturate_effect_get_type ())
|
||||
|
||||
struct _ClutterDesaturateEffectClass
|
||||
{
|
||||
ClutterOffscreenEffectClass parent_class;
|
||||
|
||||
CoglPipeline *base_pipeline;
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterDesaturateEffect,
|
||||
clutter_desaturate_effect,
|
||||
CLUTTER, DESATURATE_EFFECT,
|
||||
ClutterOffscreenEffect)
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterEffect *clutter_desaturate_effect_new (gdouble factor);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_desaturate_effect_set_factor (ClutterDesaturateEffect *effect,
|
||||
gdouble factor);
|
||||
CLUTTER_EXPORT
|
||||
gdouble clutter_desaturate_effect_get_factor (ClutterDesaturateEffect *effect);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,555 +0,0 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-easing.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
double
|
||||
clutter_linear (double t,
|
||||
double d)
|
||||
{
|
||||
return t / d;
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_quad (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / d;
|
||||
|
||||
return p * p;
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_out_quad (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / d;
|
||||
|
||||
return -1.0 * p * (p - 2);
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_out_quad (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / (d / 2);
|
||||
|
||||
if (p < 1)
|
||||
return 0.5 * p * p;
|
||||
|
||||
p -= 1;
|
||||
|
||||
return -0.5 * (p * (p - 2) - 1);
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_cubic (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / d;
|
||||
|
||||
return p * p * p;
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_out_cubic (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / d - 1;
|
||||
|
||||
return p * p * p + 1;
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_out_cubic (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / (d / 2);
|
||||
|
||||
if (p < 1)
|
||||
return 0.5 * p * p * p;
|
||||
|
||||
p -= 2;
|
||||
|
||||
return 0.5 * (p * p * p + 2);
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_quart (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / d;
|
||||
|
||||
return p * p * p * p;
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_out_quart (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / d - 1;
|
||||
|
||||
return -1.0 * (p * p * p * p - 1);
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_out_quart (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / (d / 2);
|
||||
|
||||
if (p < 1)
|
||||
return 0.5 * p * p * p * p;
|
||||
|
||||
p -= 2;
|
||||
|
||||
return -0.5 * (p * p * p * p - 2);
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_quint (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / d;
|
||||
|
||||
return p * p * p * p * p;
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_out_quint (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / d - 1;
|
||||
|
||||
return p * p * p * p * p + 1;
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_out_quint (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / (d / 2);
|
||||
|
||||
if (p < 1)
|
||||
return 0.5 * p * p * p * p * p;
|
||||
|
||||
p -= 2;
|
||||
|
||||
return 0.5 * (p * p * p * p * p + 2);
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_sine (double t,
|
||||
double d)
|
||||
{
|
||||
return -1.0 * cos (t / d * G_PI_2) + 1.0;
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_out_sine (double t,
|
||||
double d)
|
||||
{
|
||||
return sin (t / d * G_PI_2);
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_out_sine (double t,
|
||||
double d)
|
||||
{
|
||||
return -0.5 * (cos (G_PI * t / d) - 1);
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_expo (double t,
|
||||
double d)
|
||||
{
|
||||
return (t == 0) ? 0.0 : pow (2, 10 * (t / d - 1));
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_out_expo (double t,
|
||||
double d)
|
||||
{
|
||||
return (t == d) ? 1.0 : -pow (2, -10 * t / d) + 1;
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_out_expo (double t,
|
||||
double d)
|
||||
{
|
||||
double p;
|
||||
|
||||
if (t == 0)
|
||||
return 0.0;
|
||||
|
||||
if (t == d)
|
||||
return 1.0;
|
||||
|
||||
p = t / (d / 2);
|
||||
|
||||
if (p < 1)
|
||||
return 0.5 * pow (2, 10 * (p - 1));
|
||||
|
||||
p -= 1;
|
||||
|
||||
return 0.5 * (-pow (2, -10 * p) + 2);
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_circ (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / d;
|
||||
|
||||
return -1.0 * (sqrt (1 - p * p) - 1);
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_out_circ (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / d - 1;
|
||||
|
||||
return sqrt (1 - p * p);
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_out_circ (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / (d / 2);
|
||||
|
||||
if (p < 1)
|
||||
return -0.5 * (sqrt (1 - p * p) - 1);
|
||||
|
||||
p -= 2;
|
||||
|
||||
return 0.5 * (sqrt (1 - p * p) + 1);
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_elastic (double t,
|
||||
double d)
|
||||
{
|
||||
double p = d * .3;
|
||||
double s = p / 4;
|
||||
double q = t / d;
|
||||
|
||||
if (q == 1)
|
||||
return 1.0;
|
||||
|
||||
q -= 1;
|
||||
|
||||
return -(pow (2, 10 * q) * sin ((q * d - s) * (2 * G_PI) / p));
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_out_elastic (double t,
|
||||
double d)
|
||||
{
|
||||
double p = d * .3;
|
||||
double s = p / 4;
|
||||
double q = t / d;
|
||||
|
||||
if (q == 1)
|
||||
return 1.0;
|
||||
|
||||
return pow (2, -10 * q) * sin ((q * d - s) * (2 * G_PI) / p) + 1.0;
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_out_elastic (double t,
|
||||
double d)
|
||||
{
|
||||
double p = d * (.3 * 1.5);
|
||||
double s = p / 4;
|
||||
double q = t / (d / 2);
|
||||
|
||||
if (q == 2)
|
||||
return 1.0;
|
||||
|
||||
if (q < 1)
|
||||
{
|
||||
q -= 1;
|
||||
|
||||
return -.5 * (pow (2, 10 * q) * sin ((q * d - s) * (2 * G_PI) / p));
|
||||
}
|
||||
else
|
||||
{
|
||||
q -= 1;
|
||||
|
||||
return pow (2, -10 * q)
|
||||
* sin ((q * d - s) * (2 * G_PI) / p)
|
||||
* .5 + 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_back (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / d;
|
||||
|
||||
return p * p * ((1.70158 + 1) * p - 1.70158);
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_out_back (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / d - 1;
|
||||
|
||||
return p * p * ((1.70158 + 1) * p + 1.70158) + 1;
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_out_back (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / (d / 2);
|
||||
double s = 1.70158 * 1.525;
|
||||
|
||||
if (p < 1)
|
||||
return 0.5 * (p * p * ((s + 1) * p - s));
|
||||
|
||||
p -= 2;
|
||||
|
||||
return 0.5 * (p * p * ((s + 1) * p + s) + 2);
|
||||
}
|
||||
|
||||
static inline double
|
||||
ease_out_bounce_internal (double t,
|
||||
double d)
|
||||
{
|
||||
double p = t / d;
|
||||
|
||||
if (p < (1 / 2.75))
|
||||
{
|
||||
return 7.5625 * p * p;
|
||||
}
|
||||
else if (p < (2 / 2.75))
|
||||
{
|
||||
p -= (1.5 / 2.75);
|
||||
|
||||
return 7.5625 * p * p + .75;
|
||||
}
|
||||
else if (p < (2.5 / 2.75))
|
||||
{
|
||||
p -= (2.25 / 2.75);
|
||||
|
||||
return 7.5625 * p * p + .9375;
|
||||
}
|
||||
else
|
||||
{
|
||||
p -= (2.625 / 2.75);
|
||||
|
||||
return 7.5625 * p * p + .984375;
|
||||
}
|
||||
}
|
||||
|
||||
static inline double
|
||||
ease_in_bounce_internal (double t,
|
||||
double d)
|
||||
{
|
||||
return 1.0 - ease_out_bounce_internal (d - t, d);
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_bounce (double t,
|
||||
double d)
|
||||
{
|
||||
return ease_in_bounce_internal (t, d);
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_out_bounce (double t,
|
||||
double d)
|
||||
{
|
||||
return ease_out_bounce_internal (t, d);
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_in_out_bounce (double t,
|
||||
double d)
|
||||
{
|
||||
if (t < d / 2)
|
||||
return ease_in_bounce_internal (t * 2, d) * 0.5;
|
||||
else
|
||||
return ease_out_bounce_internal (t * 2 - d, d) * 0.5 + 1.0 * 0.5;
|
||||
}
|
||||
|
||||
static inline double
|
||||
ease_steps_end (double p,
|
||||
int n_steps)
|
||||
{
|
||||
return floor (p * (double) n_steps) / (double) n_steps;
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_steps_start (double t,
|
||||
double d,
|
||||
int n_steps)
|
||||
{
|
||||
return 1.0 - ease_steps_end (1.0 - (t / d), n_steps);
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_steps_end (double t,
|
||||
double d,
|
||||
int n_steps)
|
||||
{
|
||||
return ease_steps_end ((t / d), n_steps);
|
||||
}
|
||||
|
||||
static inline double
|
||||
x_for_t (double t,
|
||||
double x_1,
|
||||
double x_2)
|
||||
{
|
||||
double omt = 1.0 - t;
|
||||
|
||||
return 3.0 * omt * omt * t * x_1
|
||||
+ 3.0 * omt * t * t * x_2
|
||||
+ t * t * t;
|
||||
}
|
||||
|
||||
static inline double
|
||||
y_for_t (double t,
|
||||
double y_1,
|
||||
double y_2)
|
||||
{
|
||||
double omt = 1.0 - t;
|
||||
|
||||
return 3.0 * omt * omt * t * y_1
|
||||
+ 3.0 * omt * t * t * y_2
|
||||
+ t * t * t;
|
||||
}
|
||||
|
||||
static inline double
|
||||
t_for_x (double x,
|
||||
double x_1,
|
||||
double x_2)
|
||||
{
|
||||
double min_t = 0, max_t = 1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 30; ++i)
|
||||
{
|
||||
double guess_t = (min_t + max_t) / 2.0;
|
||||
double guess_x = x_for_t (guess_t, x_1, x_2);
|
||||
|
||||
if (x < guess_x)
|
||||
max_t = guess_t;
|
||||
else
|
||||
min_t = guess_t;
|
||||
}
|
||||
|
||||
return (min_t + max_t) / 2.0;
|
||||
}
|
||||
|
||||
double
|
||||
clutter_ease_cubic_bezier (double t,
|
||||
double d,
|
||||
double x_1,
|
||||
double y_1,
|
||||
double x_2,
|
||||
double y_2)
|
||||
{
|
||||
double p = t / d;
|
||||
|
||||
if (p == 0.0)
|
||||
return 0.0;
|
||||
|
||||
if (p == 1.0)
|
||||
return 1.0;
|
||||
|
||||
return y_for_t (t_for_x (p, x_1, x_2), y_1, y_2);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* _clutter_animation_modes:
|
||||
*
|
||||
* A mapping of animation modes and easing functions.
|
||||
*/
|
||||
static const struct {
|
||||
ClutterAnimationMode mode;
|
||||
ClutterEasingFunc func;
|
||||
const char *name;
|
||||
} _clutter_animation_modes[] = {
|
||||
{ CLUTTER_CUSTOM_MODE, NULL, "custom" },
|
||||
|
||||
{ CLUTTER_LINEAR, clutter_linear, "linear" },
|
||||
{ CLUTTER_EASE_IN_QUAD, clutter_ease_in_quad, "easeInQuad" },
|
||||
{ CLUTTER_EASE_OUT_QUAD, clutter_ease_out_quad, "easeOutQuad" },
|
||||
{ CLUTTER_EASE_IN_OUT_QUAD, clutter_ease_in_out_quad, "easeInOutQuad" },
|
||||
{ CLUTTER_EASE_IN_CUBIC, clutter_ease_in_cubic, "easeInCubic" },
|
||||
{ CLUTTER_EASE_OUT_CUBIC, clutter_ease_out_cubic, "easeOutCubic" },
|
||||
{ CLUTTER_EASE_IN_OUT_CUBIC, clutter_ease_in_out_cubic, "easeInOutCubic" },
|
||||
{ CLUTTER_EASE_IN_QUART, clutter_ease_in_quart, "easeInQuart" },
|
||||
{ CLUTTER_EASE_OUT_QUART, clutter_ease_out_quart, "easeOutQuart" },
|
||||
{ CLUTTER_EASE_IN_OUT_QUART, clutter_ease_in_out_quart, "easeInOutQuart" },
|
||||
{ CLUTTER_EASE_IN_QUINT, clutter_ease_in_quint, "easeInQuint" },
|
||||
{ CLUTTER_EASE_OUT_QUINT, clutter_ease_out_quint, "easeOutQuint" },
|
||||
{ CLUTTER_EASE_IN_OUT_QUINT, clutter_ease_in_out_quint, "easeInOutQuint" },
|
||||
{ CLUTTER_EASE_IN_SINE, clutter_ease_in_sine, "easeInSine" },
|
||||
{ CLUTTER_EASE_OUT_SINE, clutter_ease_out_sine, "easeOutSine" },
|
||||
{ CLUTTER_EASE_IN_OUT_SINE, clutter_ease_in_out_sine, "easeInOutSine" },
|
||||
{ CLUTTER_EASE_IN_EXPO, clutter_ease_in_expo, "easeInExpo" },
|
||||
{ CLUTTER_EASE_OUT_EXPO, clutter_ease_out_expo, "easeOutExpo" },
|
||||
{ CLUTTER_EASE_IN_OUT_EXPO, clutter_ease_in_out_expo, "easeInOutExpo" },
|
||||
{ CLUTTER_EASE_IN_CIRC, clutter_ease_in_circ, "easeInCirc" },
|
||||
{ CLUTTER_EASE_OUT_CIRC, clutter_ease_out_circ, "easeOutCirc" },
|
||||
{ CLUTTER_EASE_IN_OUT_CIRC, clutter_ease_in_out_circ, "easeInOutCirc" },
|
||||
{ CLUTTER_EASE_IN_ELASTIC, clutter_ease_in_elastic, "easeInElastic" },
|
||||
{ CLUTTER_EASE_OUT_ELASTIC, clutter_ease_out_elastic, "easeOutElastic" },
|
||||
{ CLUTTER_EASE_IN_OUT_ELASTIC, clutter_ease_in_out_elastic, "easeInOutElastic" },
|
||||
{ CLUTTER_EASE_IN_BACK, clutter_ease_in_back, "easeInBack" },
|
||||
{ CLUTTER_EASE_OUT_BACK, clutter_ease_out_back, "easeOutBack" },
|
||||
{ CLUTTER_EASE_IN_OUT_BACK, clutter_ease_in_out_back, "easeInOutBack" },
|
||||
{ CLUTTER_EASE_IN_BOUNCE, clutter_ease_in_bounce, "easeInBounce" },
|
||||
{ CLUTTER_EASE_OUT_BOUNCE, clutter_ease_out_bounce, "easeOutBounce" },
|
||||
{ CLUTTER_EASE_IN_OUT_BOUNCE, clutter_ease_in_out_bounce, "easeInOutBounce" },
|
||||
|
||||
/* the parametrized functions need a cast */
|
||||
{ CLUTTER_STEPS, (ClutterEasingFunc) clutter_ease_steps_end, "steps" },
|
||||
{ CLUTTER_STEP_START, (ClutterEasingFunc) clutter_ease_steps_start, "stepStart" },
|
||||
{ CLUTTER_STEP_END, (ClutterEasingFunc) clutter_ease_steps_end, "stepEnd" },
|
||||
|
||||
{ CLUTTER_CUBIC_BEZIER, (ClutterEasingFunc) clutter_ease_cubic_bezier, "cubicBezier" },
|
||||
{ CLUTTER_EASE, (ClutterEasingFunc) clutter_ease_cubic_bezier, "ease" },
|
||||
{ CLUTTER_EASE_IN, (ClutterEasingFunc) clutter_ease_cubic_bezier, "easeIn" },
|
||||
{ CLUTTER_EASE_OUT, (ClutterEasingFunc) clutter_ease_cubic_bezier, "easeOut" },
|
||||
{ CLUTTER_EASE_IN_OUT, (ClutterEasingFunc) clutter_ease_cubic_bezier, "easeInOut" },
|
||||
|
||||
{ CLUTTER_ANIMATION_LAST, NULL, "sentinel" },
|
||||
};
|
||||
|
||||
ClutterEasingFunc
|
||||
clutter_get_easing_func_for_mode (ClutterAnimationMode mode)
|
||||
{
|
||||
g_assert (_clutter_animation_modes[mode].mode == mode);
|
||||
g_assert (_clutter_animation_modes[mode].func != NULL);
|
||||
|
||||
return _clutter_animation_modes[mode].func;
|
||||
}
|
||||
|
||||
const char *
|
||||
clutter_get_easing_name_for_mode (ClutterAnimationMode mode)
|
||||
{
|
||||
g_assert (_clutter_animation_modes[mode].mode == mode);
|
||||
g_assert (_clutter_animation_modes[mode].func != NULL);
|
||||
|
||||
return _clutter_animation_modes[mode].name;
|
||||
}
|
||||
|
||||
double
|
||||
clutter_easing_for_mode (ClutterAnimationMode mode,
|
||||
double t,
|
||||
double d)
|
||||
{
|
||||
g_assert (_clutter_animation_modes[mode].mode == mode);
|
||||
g_assert (_clutter_animation_modes[mode].func != NULL);
|
||||
|
||||
return _clutter_animation_modes[mode].func (t, d);
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*< private >
|
||||
* ClutterEasingFunc:
|
||||
* @t: elapsed time
|
||||
* @d: total duration
|
||||
*
|
||||
* Internal type for the easing functions used by Clutter.
|
||||
*
|
||||
* Return value: the interpolated value, between -1.0 and 2.0
|
||||
*/
|
||||
typedef double (* ClutterEasingFunc) (double t, double d);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
ClutterEasingFunc clutter_get_easing_func_for_mode (ClutterAnimationMode mode);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
const char * clutter_get_easing_name_for_mode (ClutterAnimationMode mode);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_easing_for_mode (ClutterAnimationMode mode,
|
||||
double t,
|
||||
double d);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_linear (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_quad (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_out_quad (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_out_quad (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_cubic (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_out_cubic (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_out_cubic (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_quart (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_out_quart (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_out_quart (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_quint (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_out_quint (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_out_quint (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_sine (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_out_sine (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_out_sine (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_expo (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_out_expo (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_out_expo (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_circ (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_out_circ (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_out_circ (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_elastic (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_out_elastic (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_out_elastic (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_back (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_out_back (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_out_back (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_bounce (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_out_bounce (double t,
|
||||
double d);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_in_out_bounce (double t,
|
||||
double d);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_steps_start (double t,
|
||||
double d,
|
||||
int steps);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_steps_end (double t,
|
||||
double d,
|
||||
int steps);
|
||||
G_GNUC_INTERNAL
|
||||
double clutter_ease_cubic_bezier (double t,
|
||||
double d,
|
||||
double x_1,
|
||||
double y_1,
|
||||
double x_2,
|
||||
double y_2);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "clutter/clutter-effect.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
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,
|
||||
ClutterPickContext *pick_context);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,397 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterEffect:
|
||||
*
|
||||
* Base class for actor effects
|
||||
*
|
||||
* The #ClutterEffect class provides a default type and API for creating
|
||||
* effects for generic actors.
|
||||
*
|
||||
* Effects are a #ClutterActorMeta sub-class that modify the way an actor
|
||||
* is painted in a way that is not part of the actor's implementation.
|
||||
*
|
||||
* Effects should be the preferred way to affect the paint sequence of an
|
||||
* actor without sub-classing the actor itself and overriding the
|
||||
* [vfunc@Clutter.Actor.paint] virtual function.
|
||||
*
|
||||
* ## Implementing a ClutterEffect
|
||||
*
|
||||
* Creating a sub-class of #ClutterEffect requires overriding the
|
||||
* [vfunc@Clutter.Effect.paint] method. The implementation of the function should look
|
||||
* something like this:
|
||||
*
|
||||
* ```c
|
||||
* void effect_paint (ClutterEffect *effect, ClutterEffectPaintFlags flags)
|
||||
* {
|
||||
* // Set up initialisation of the paint such as binding a
|
||||
* // CoglOffscreen or other operations
|
||||
*
|
||||
* // Chain to the next item in the paint sequence. This will either call
|
||||
* // ‘paint’ on the next effect or just paint the actor if this is
|
||||
* // the last effect.
|
||||
* ClutterActor *actor =
|
||||
* clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
|
||||
*
|
||||
* clutter_actor_continue_paint (actor);
|
||||
*
|
||||
* // perform any cleanup of state, such as popping the CoglOffscreen
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* The effect can optionally avoid calling clutter_actor_continue_paint() to skip any
|
||||
* further stages of the paint sequence. This is useful for example if the effect
|
||||
* contains a cached image of the actor. In that case it can optimise painting by
|
||||
* avoiding the actor paint and instead painting the cached image.
|
||||
*
|
||||
* The %CLUTTER_EFFECT_PAINT_ACTOR_DIRTY flag is useful in this case. Clutter will set
|
||||
* this flag when a redraw has been queued on the actor since it was last painted. The
|
||||
* effect can use this information to decide if the cached image is still valid.
|
||||
*
|
||||
* ## A simple ClutterEffect implementation
|
||||
*
|
||||
* The example below creates two rectangles: one will be painted "behind" the actor,
|
||||
* while another will be painted "on top" of the actor.
|
||||
*
|
||||
* The #ClutterActorMetaClass.set_actor() implementation will create the two pipelines
|
||||
* used for the two different rectangles; the #ClutterEffectClass.paint() implementation
|
||||
* will paint the first pipeline using cogl_rectangle(), before continuing and then it
|
||||
* will paint paint the second pipeline after.
|
||||
*
|
||||
* ```c
|
||||
* typedef struct {
|
||||
* ClutterEffect parent_instance;
|
||||
*
|
||||
* CoglPipeline *rect_1;
|
||||
* CoglPipeline *rect_2;
|
||||
* } MyEffect;
|
||||
*
|
||||
* typedef struct _ClutterEffectClass MyEffectClass;
|
||||
*
|
||||
* G_DEFINE_TYPE (MyEffect, my_effect, CLUTTER_TYPE_EFFECT);
|
||||
*
|
||||
* static void
|
||||
* my_effect_set_actor (ClutterActorMeta *meta,
|
||||
* ClutterActor *actor)
|
||||
* {
|
||||
* MyEffect *self = MY_EFFECT (meta);
|
||||
* CoglColor color;
|
||||
*
|
||||
* // Clear the previous state //
|
||||
* if (self->rect_1)
|
||||
* {
|
||||
* g_object_unref (self->rect_1);
|
||||
* self->rect_1 = NULL;
|
||||
* }
|
||||
*
|
||||
* if (self->rect_2)
|
||||
* {
|
||||
* g_object_unref (self->rect_2);
|
||||
* self->rect_2 = NULL;
|
||||
* }
|
||||
*
|
||||
* // Maintain a pointer to the actor
|
||||
* self->actor = actor;
|
||||
*
|
||||
* // If we've been detached by the actor then we should just bail out here
|
||||
* if (self->actor == NULL)
|
||||
* return;
|
||||
*
|
||||
* // Create a red pipeline
|
||||
* self->rect_1 = cogl_pipeline_new ();
|
||||
* cogl_color_init_from_4f (&color, 1.0, 1.0, 1.0, 1.0);
|
||||
* cogl_pipeline_set_color (self->rect_1, &color);
|
||||
*
|
||||
* // Create a green pipeline
|
||||
* self->rect_2 = cogl_pipeline_new ();
|
||||
* cogl_color_init_from_4f (&color, 0.0, 1.0, 0.0, 1.0);
|
||||
* cogl_pipeline_set_color (self->rect_2, &color);
|
||||
* }
|
||||
*
|
||||
* static gboolean
|
||||
* my_effect_paint (ClutterEffect *effect)
|
||||
* {
|
||||
* MyEffect *self = MY_EFFECT (effect);
|
||||
* gfloat width, height;
|
||||
*
|
||||
* clutter_actor_get_size (self->actor, &width, &height);
|
||||
*
|
||||
* // Paint the first rectangle in the upper left quadrant
|
||||
* cogl_set_source (self->rect_1);
|
||||
* cogl_rectangle (0, 0, width / 2, height / 2);
|
||||
*
|
||||
* // Continue to the rest of the paint sequence
|
||||
* clutter_actor_continue_paint (self->actor);
|
||||
*
|
||||
* // Paint the second rectangle in the lower right quadrant
|
||||
* cogl_set_source (self->rect_2);
|
||||
* cogl_rectangle (width / 2, height / 2, width, height);
|
||||
* }
|
||||
*
|
||||
* static void
|
||||
* my_effect_class_init (MyEffectClass *klass)
|
||||
* {
|
||||
* ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
|
||||
*
|
||||
* meta_class->set_actor = my_effect_set_actor;
|
||||
*
|
||||
* klass->paint = my_effect_paint;
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-effect.h"
|
||||
|
||||
#include "clutter/clutter-actor-meta-private.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-effect-private.h"
|
||||
#include "clutter/clutter-enum-types.h"
|
||||
#include "clutter/clutter-marshal.h"
|
||||
#include "clutter/clutter-paint-node-private.h"
|
||||
#include "clutter/clutter-paint-nodes.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#include "clutter/clutter-actor-private.h"
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (ClutterEffect,
|
||||
clutter_effect,
|
||||
CLUTTER_TYPE_ACTOR_META);
|
||||
|
||||
static gboolean
|
||||
clutter_effect_real_pre_paint (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_effect_real_post_paint (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_effect_real_modify_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_effect_real_pick (ClutterEffect *effect,
|
||||
ClutterPickContext *pick_context)
|
||||
{
|
||||
ClutterActorMeta *actor_meta = CLUTTER_ACTOR_META (effect);
|
||||
ClutterActor *actor;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (actor_meta);
|
||||
clutter_actor_continue_pick (actor, pick_context);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_effect_set_enabled (ClutterActorMeta *meta,
|
||||
gboolean is_enabled)
|
||||
{
|
||||
ClutterActorMetaClass *parent_class =
|
||||
CLUTTER_ACTOR_META_CLASS (clutter_effect_parent_class);
|
||||
ClutterActor *actor;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (meta);
|
||||
if (actor)
|
||||
clutter_actor_queue_redraw (actor);
|
||||
|
||||
parent_class->set_enabled (meta, is_enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_effect_class_init (ClutterEffectClass *klass)
|
||||
{
|
||||
ClutterActorMetaClass *actor_meta_class = CLUTTER_ACTOR_META_CLASS (klass);
|
||||
|
||||
actor_meta_class->set_enabled = clutter_effect_set_enabled;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_effect_init (ClutterEffect *self)
|
||||
{
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_effect_pick (ClutterEffect *effect,
|
||||
ClutterPickContext *pick_context)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_EFFECT (effect));
|
||||
|
||||
CLUTTER_EFFECT_GET_CLASS (effect)->pick (effect, pick_context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_effect_modify_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE);
|
||||
g_return_val_if_fail (volume != NULL, FALSE);
|
||||
|
||||
return CLUTTER_EFFECT_GET_CLASS (effect)->modify_paint_volume (effect,
|
||||
volume);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_effect_has_custom_paint_volume (ClutterEffect *effect)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE);
|
||||
|
||||
return CLUTTER_EFFECT_GET_CLASS (effect)->modify_paint_volume != clutter_effect_real_modify_paint_volume;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_effect_queue_repaint:
|
||||
* @effect: A #ClutterEffect which needs redrawing
|
||||
*
|
||||
* Queues a repaint of the effect. The effect can detect when the ‘paint’
|
||||
* method is called as a result of this function because it will not
|
||||
* have the %CLUTTER_EFFECT_PAINT_ACTOR_DIRTY flag set. In that case the
|
||||
* effect is free to assume that the actor has not changed its
|
||||
* appearance since the last time it was painted so it doesn't need to
|
||||
* call clutter_actor_continue_paint() if it can draw a cached
|
||||
* image. This is mostly intended for effects that are using a
|
||||
* %CoglOffscreen to redirect the actor (such as
|
||||
* %ClutterOffscreenEffect). In that case the effect can save a bit of
|
||||
* rendering time by painting the cached texture without causing the
|
||||
* entire actor to be painted.
|
||||
*
|
||||
* This function can be used by effects that have their own animatable
|
||||
* parameters. For example, an effect which adds a varying degree of a
|
||||
* red tint to an actor by redirecting it through a CoglOffscreen
|
||||
* might have a property to specify the level of tint. When this value
|
||||
* changes, the underlying actor doesn't need to be redrawn so the
|
||||
* effect can call clutter_effect_queue_repaint() to make sure the
|
||||
* effect is repainted.
|
||||
*
|
||||
* Note however that modifying the position of the parent of an actor
|
||||
* may change the appearance of the actor because its transformation
|
||||
* matrix would change. In this case a redraw wouldn't be queued on
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* anything queues a redraw on the actor without specifying an effect
|
||||
* or with an effect that is lower in the chain of effects than this
|
||||
* one then that will override this call. In that case this effect
|
||||
* will instead be called with the %CLUTTER_EFFECT_PAINT_ACTOR_DIRTY
|
||||
* flag set.
|
||||
*/
|
||||
void
|
||||
clutter_effect_queue_repaint (ClutterEffect *effect)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_EFFECT (effect));
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
|
||||
|
||||
/* If the effect has no actor then nothing needs to be done */
|
||||
if (actor != NULL)
|
||||
_clutter_actor_queue_redraw_full (actor,
|
||||
NULL, /* clip volume */
|
||||
effect /* effect */);
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-actor-meta.h"
|
||||
#include "clutter/clutter-paint-context.h"
|
||||
#include "clutter/clutter-pick-context.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_EFFECT (clutter_effect_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterEffect,
|
||||
clutter_effect,
|
||||
CLUTTER,
|
||||
EFFECT,
|
||||
ClutterActorMeta)
|
||||
|
||||
/**
|
||||
* ClutterEffectClass:
|
||||
* @pre_paint: virtual function
|
||||
* @post_paint: virtual function
|
||||
* @modify_paint_volume: virtual function
|
||||
* @paint: virtual function
|
||||
* @pick: virtual function
|
||||
*
|
||||
* The #ClutterEffectClass structure contains only private data
|
||||
*/
|
||||
struct _ClutterEffectClass
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterActorMetaClass parent_class;
|
||||
|
||||
/*< 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,
|
||||
ClutterPickContext *pick_context);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_effect_queue_repaint (ClutterEffect *effect);
|
||||
|
||||
/*
|
||||
* ClutterActor API
|
||||
*/
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_add_effect (ClutterActor *self,
|
||||
ClutterEffect *effect);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_add_effect_with_name (ClutterActor *self,
|
||||
const gchar *name,
|
||||
ClutterEffect *effect);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_remove_effect (ClutterActor *self,
|
||||
ClutterEffect *effect);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_remove_effect_by_name (ClutterActor *self,
|
||||
const gchar *name);
|
||||
CLUTTER_EXPORT
|
||||
GList * clutter_actor_get_effects (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEffect *clutter_actor_get_effect (ClutterActor *self,
|
||||
const gchar *name);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_clear_effects (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_has_effects (ClutterActor *self);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,40 +0,0 @@
|
||||
/*** BEGIN file-header ***/
|
||||
#include "config.h"
|
||||
#include "clutter/clutter-enum-types.h"
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN file-production ***/
|
||||
|
||||
/* enumerations from "@filename@" */
|
||||
#include "@filename@"
|
||||
|
||||
/*** END file-production ***/
|
||||
|
||||
/*** BEGIN value-header ***/
|
||||
GType
|
||||
@enum_name@_get_type (void)
|
||||
{
|
||||
static size_t g_enum_type_id = 0;
|
||||
|
||||
if (g_once_init_enter (&g_enum_type_id))
|
||||
{
|
||||
static const G@Type@Value values[] = {
|
||||
/*** END value-header ***/
|
||||
|
||||
/*** BEGIN value-production ***/
|
||||
{ @VALUENAME@, "@VALUENAME@", "@valuenick@" },
|
||||
/*** END value-production ***/
|
||||
|
||||
/*** BEGIN value-tail ***/
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
GType id;
|
||||
|
||||
id = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
|
||||
|
||||
g_once_init_leave (&g_enum_type_id, id);
|
||||
}
|
||||
|
||||
return g_enum_type_id;
|
||||
}
|
||||
/*** END value-tail ***/
|
||||
@@ -1,27 +0,0 @@
|
||||
/*** BEGIN file-header ***/
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN file-production ***/
|
||||
/* enumerations from "@basename@" */
|
||||
/*** END file-production ***/
|
||||
|
||||
/*** BEGIN value-header ***/
|
||||
CLUTTER_EXPORT GType @enum_name@_get_type (void) G_GNUC_CONST;
|
||||
#define CLUTTER_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
|
||||
|
||||
/*** END value-header ***/
|
||||
|
||||
/*** BEGIN file-tail ***/
|
||||
G_END_DECLS
|
||||
|
||||
/*** END file-tail ***/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,188 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "clutter/clutter-event.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _ClutterModifierSet ClutterModifierSet;
|
||||
|
||||
struct _ClutterModifierSet
|
||||
{
|
||||
ClutterModifierType pressed;
|
||||
ClutterModifierType latched;
|
||||
ClutterModifierType locked;
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_key_new (ClutterEventType type,
|
||||
ClutterEventFlags flags,
|
||||
int64_t timestamp_us,
|
||||
ClutterInputDevice *source_device,
|
||||
ClutterModifierSet raw_modifiers,
|
||||
ClutterModifierType modifiers,
|
||||
uint32_t keyval,
|
||||
uint32_t evcode,
|
||||
uint32_t keycode,
|
||||
gunichar unicode_value);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_button_new (ClutterEventType type,
|
||||
ClutterEventFlags flags,
|
||||
int64_t timestamp_us,
|
||||
ClutterInputDevice *source_device,
|
||||
ClutterInputDeviceTool *tool,
|
||||
ClutterModifierType modifiers,
|
||||
graphene_point_t coords,
|
||||
int button,
|
||||
uint32_t evcode,
|
||||
double *axes);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_motion_new (ClutterEventFlags flags,
|
||||
int64_t timestamp_us,
|
||||
ClutterInputDevice *source_device,
|
||||
ClutterInputDeviceTool *tool,
|
||||
ClutterModifierType modifiers,
|
||||
graphene_point_t coords,
|
||||
graphene_point_t delta,
|
||||
graphene_point_t delta_unaccel,
|
||||
graphene_point_t delta_constrained,
|
||||
double *axes);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_scroll_smooth_new (ClutterEventFlags flags,
|
||||
int64_t timestamp_us,
|
||||
ClutterInputDevice *source_device,
|
||||
ClutterInputDeviceTool *tool,
|
||||
ClutterModifierType modifiers,
|
||||
graphene_point_t coords,
|
||||
graphene_point_t delta,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags finish_flags);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_scroll_discrete_new (ClutterEventFlags flags,
|
||||
int64_t timestamp_us,
|
||||
ClutterInputDevice *source_device,
|
||||
ClutterInputDeviceTool *tool,
|
||||
ClutterModifierType modifiers,
|
||||
graphene_point_t coords,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollDirection direction);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_crossing_new (ClutterEventType type,
|
||||
ClutterEventFlags flags,
|
||||
int64_t timestamp_us,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence,
|
||||
graphene_point_t coords,
|
||||
ClutterActor *source,
|
||||
ClutterActor *related);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_touch_new (ClutterEventType type,
|
||||
ClutterEventFlags flags,
|
||||
int64_t timestamp_us,
|
||||
ClutterInputDevice *source_device,
|
||||
ClutterEventSequence *sequence,
|
||||
ClutterModifierType modifiers,
|
||||
graphene_point_t coords);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_touch_cancel_new (ClutterEventFlags flags,
|
||||
int64_t timestamp_us,
|
||||
ClutterInputDevice *source_device,
|
||||
ClutterEventSequence *sequence);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_proximity_new (ClutterEventType type,
|
||||
ClutterEventFlags flags,
|
||||
int64_t timestamp_us,
|
||||
ClutterInputDevice *source_device,
|
||||
ClutterInputDeviceTool *tool);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_touchpad_pinch_new (ClutterEventFlags flags,
|
||||
int64_t timestamp_us,
|
||||
ClutterInputDevice *source_device,
|
||||
ClutterTouchpadGesturePhase phase,
|
||||
uint32_t fingers,
|
||||
graphene_point_t coords,
|
||||
graphene_point_t delta,
|
||||
graphene_point_t delta_unaccel,
|
||||
float angle,
|
||||
float scale);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_touchpad_swipe_new (ClutterEventFlags flags,
|
||||
int64_t timestamp_us,
|
||||
ClutterInputDevice *source_device,
|
||||
ClutterTouchpadGesturePhase phase,
|
||||
uint32_t fingers,
|
||||
graphene_point_t coords,
|
||||
graphene_point_t delta,
|
||||
graphene_point_t delta_unaccel);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_touchpad_hold_new (ClutterEventFlags flags,
|
||||
int64_t timestamp_us,
|
||||
ClutterInputDevice *source_device,
|
||||
ClutterTouchpadGesturePhase phase,
|
||||
uint32_t fingers,
|
||||
graphene_point_t coords);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_pad_button_new (ClutterEventType type,
|
||||
ClutterEventFlags flags,
|
||||
int64_t timestamp_us,
|
||||
ClutterInputDevice *source_device,
|
||||
uint32_t button,
|
||||
uint32_t group,
|
||||
uint32_t mode);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_pad_strip_new (ClutterEventFlags flags,
|
||||
int64_t timestamp_us,
|
||||
ClutterInputDevice *source_device,
|
||||
ClutterInputDevicePadSource strip_source,
|
||||
uint32_t strip,
|
||||
uint32_t group,
|
||||
double value,
|
||||
uint32_t mode);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_pad_ring_new (ClutterEventFlags flags,
|
||||
int64_t timestamp_us,
|
||||
ClutterInputDevice *source_device,
|
||||
ClutterInputDevicePadSource ring_source,
|
||||
uint32_t ring,
|
||||
uint32_t group,
|
||||
double angle,
|
||||
uint32_t mode);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_device_notify_new (ClutterEventType type,
|
||||
ClutterEventFlags flags,
|
||||
int64_t timestamp_us,
|
||||
ClutterInputDevice *source_device);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_im_new (ClutterEventType type,
|
||||
ClutterEventFlags flags,
|
||||
int64_t timestamp_us,
|
||||
ClutterSeat *seat,
|
||||
const char *text,
|
||||
int32_t offset,
|
||||
int32_t anchor,
|
||||
uint32_t len,
|
||||
ClutterPreeditResetMode mode);
|
||||
|
||||
/* Reinjecting queued events for processing */
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_process_event (ClutterStage *stage,
|
||||
ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean _clutter_event_process_filters (ClutterEvent *event,
|
||||
ClutterActor *event_actor);
|
||||
|
||||
/* clears the event queue inside the main context */
|
||||
void _clutter_clear_events_queue (void);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_event_push (const ClutterEvent *event,
|
||||
gboolean do_copy);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
const char * clutter_event_get_name (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
char * clutter_event_describe (const ClutterEvent *event);
|
||||
|
||||
G_END_DECLS
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,299 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2006 OpenedHand
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
#include "clutter/clutter-input-device.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_EVENT (clutter_event_get_type ())
|
||||
#define CLUTTER_TYPE_EVENT_SEQUENCE (clutter_event_sequence_get_type ())
|
||||
|
||||
/**
|
||||
* CLUTTER_PRIORITY_EVENTS:
|
||||
*
|
||||
* Priority for event handling.
|
||||
*/
|
||||
#define CLUTTER_PRIORITY_EVENTS (G_PRIORITY_DEFAULT)
|
||||
|
||||
/**
|
||||
* CLUTTER_CURRENT_TIME:
|
||||
*
|
||||
* Default value for "now".
|
||||
*/
|
||||
#define CLUTTER_CURRENT_TIME (0L)
|
||||
|
||||
/**
|
||||
* CLUTTER_EVENT_PROPAGATE:
|
||||
*
|
||||
* Continues the propagation of an event; this macro should be
|
||||
* used in event-related signals.
|
||||
*/
|
||||
#define CLUTTER_EVENT_PROPAGATE (FALSE)
|
||||
|
||||
/**
|
||||
* CLUTTER_EVENT_STOP:
|
||||
*
|
||||
* Stops the propagation of an event; this macro should be used
|
||||
* in event-related signals.
|
||||
*/
|
||||
#define CLUTTER_EVENT_STOP (TRUE)
|
||||
|
||||
/**
|
||||
* CLUTTER_BUTTON_PRIMARY:
|
||||
*
|
||||
* The primary button of a pointer device.
|
||||
*
|
||||
* This is typically the left mouse button in a right-handed
|
||||
* mouse configuration.
|
||||
*/
|
||||
#define CLUTTER_BUTTON_PRIMARY (1)
|
||||
|
||||
/**
|
||||
* CLUTTER_BUTTON_MIDDLE:
|
||||
*
|
||||
* The middle button of a pointer device.
|
||||
*/
|
||||
#define CLUTTER_BUTTON_MIDDLE (2)
|
||||
|
||||
/**
|
||||
* CLUTTER_BUTTON_SECONDARY:
|
||||
*
|
||||
* The secondary button of a pointer device.
|
||||
*
|
||||
* This is typically the right mouse button in a right-handed
|
||||
* mouse configuration.
|
||||
*/
|
||||
#define CLUTTER_BUTTON_SECONDARY (3)
|
||||
|
||||
typedef struct _ClutterAnyEvent ClutterAnyEvent;
|
||||
typedef struct _ClutterButtonEvent ClutterButtonEvent;
|
||||
typedef struct _ClutterKeyEvent ClutterKeyEvent;
|
||||
typedef struct _ClutterMotionEvent ClutterMotionEvent;
|
||||
typedef struct _ClutterScrollEvent ClutterScrollEvent;
|
||||
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;
|
||||
|
||||
/**
|
||||
* ClutterEventFilterFunc:
|
||||
* @event: the event that is going to be emitted
|
||||
* @event_actor: the current device actor of the events device
|
||||
* @user_data: the data pointer passed to [func@Clutter.Event.add_filter]
|
||||
*
|
||||
* A function pointer type used by event filters that are added with
|
||||
* [func@Clutter.Event.add_filter].
|
||||
*
|
||||
* Return value: %CLUTTER_EVENT_STOP to indicate that the event
|
||||
* has been handled or %CLUTTER_EVENT_PROPAGATE otherwise.
|
||||
* Returning %CLUTTER_EVENT_STOP skips any further filter
|
||||
* functions and prevents the signal emission for the event.
|
||||
*/
|
||||
typedef gboolean (* ClutterEventFilterFunc) (const ClutterEvent *event,
|
||||
ClutterActor *event_actor,
|
||||
gpointer user_data);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_event_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_event_sequence_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_events_pending (void);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_get (void);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_event_put (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
guint clutter_event_add_filter (ClutterStage *stage,
|
||||
ClutterEventFilterFunc func,
|
||||
GDestroyNotify notify,
|
||||
gpointer user_data);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_event_remove_filter (guint id);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_copy (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_event_free (ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterEventType clutter_event_type (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEventFlags clutter_event_get_flags (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
guint32 clutter_event_get_time (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
ClutterModifierType clutter_event_get_state (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
ClutterInputDevice * clutter_event_get_device (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterInputDevice * clutter_event_get_source_device (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterInputDeviceTool *clutter_event_get_device_tool (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_event_get_source (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
ClutterInputDeviceType clutter_event_get_device_type (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_event_get_coords (const ClutterEvent *event,
|
||||
gfloat *x,
|
||||
gfloat *y);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_event_get_position (const ClutterEvent *event,
|
||||
graphene_point_t *position);
|
||||
CLUTTER_EXPORT
|
||||
float clutter_event_get_distance (const ClutterEvent *source,
|
||||
const ClutterEvent *target);
|
||||
CLUTTER_EXPORT
|
||||
double clutter_event_get_angle (const ClutterEvent *source,
|
||||
const ClutterEvent *target);
|
||||
CLUTTER_EXPORT
|
||||
gdouble * clutter_event_get_axes (const ClutterEvent *event,
|
||||
guint *n_axes);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_event_has_shift_modifier (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_event_has_control_modifier (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_event_is_pointer_emulated (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
guint clutter_event_get_key_symbol (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
guint16 clutter_event_get_key_code (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
gunichar clutter_event_get_key_unicode (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_event_get_key_state (const ClutterEvent *event,
|
||||
ClutterModifierType *pressed,
|
||||
ClutterModifierType *latched,
|
||||
ClutterModifierType *locked);
|
||||
CLUTTER_EXPORT
|
||||
guint32 clutter_event_get_button (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_event_get_related (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
ClutterScrollDirection clutter_event_get_scroll_direction (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_event_get_scroll_delta (const ClutterEvent *event,
|
||||
gdouble *dx,
|
||||
gdouble *dy);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterEventSequence * clutter_event_get_event_sequence (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
guint32 clutter_keysym_to_unicode (guint keyval);
|
||||
CLUTTER_EXPORT
|
||||
guint clutter_unicode_to_keysym (guint32 wc);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
guint32 clutter_get_current_event_time (void);
|
||||
CLUTTER_EXPORT
|
||||
const ClutterEvent * clutter_get_current_event (void);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
guint clutter_event_get_touchpad_gesture_finger_count (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gdouble clutter_event_get_gesture_pinch_angle_delta (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gdouble clutter_event_get_gesture_pinch_scale (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterTouchpadGesturePhase clutter_event_get_gesture_phase (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_event_get_gesture_motion_delta (const ClutterEvent *event,
|
||||
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);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterScrollFinishFlags clutter_event_get_scroll_finish_flags (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
guint clutter_event_get_mode_group (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_event_get_pad_details (const ClutterEvent *event,
|
||||
guint *number,
|
||||
guint *mode,
|
||||
ClutterInputDevicePadSource *source,
|
||||
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,
|
||||
double *dx_constrained,
|
||||
double *dy_constrained);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
const char * clutter_event_get_im_text (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_event_get_im_location (const ClutterEvent *event,
|
||||
int32_t *offset,
|
||||
int32_t *anchor);
|
||||
CLUTTER_EXPORT
|
||||
uint32_t clutter_event_get_im_delete_length (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
ClutterPreeditResetMode clutter_event_get_im_preedit_reset_mode (const ClutterEvent *event);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2009 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*
|
||||
* Based on the fixed layout code inside clutter-group.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterFixedLayout:
|
||||
*
|
||||
* A fixed layout manager
|
||||
*
|
||||
* #ClutterFixedLayout is a layout manager implementing the same
|
||||
* layout policies as #ClutterGroup.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-fixed-layout.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
G_DEFINE_TYPE (ClutterFixedLayout,
|
||||
clutter_fixed_layout,
|
||||
CLUTTER_TYPE_LAYOUT_MANAGER);
|
||||
|
||||
static void
|
||||
clutter_fixed_layout_get_preferred_width (ClutterLayoutManager *manager,
|
||||
ClutterActor *container,
|
||||
gfloat for_height,
|
||||
gfloat *min_width_p,
|
||||
gfloat *nat_width_p)
|
||||
{
|
||||
ClutterActor *actor, *child;
|
||||
gdouble min_right;
|
||||
gdouble natural_right;
|
||||
|
||||
min_right = 0;
|
||||
natural_right = 0;
|
||||
|
||||
actor = CLUTTER_ACTOR (container);
|
||||
|
||||
for (child = clutter_actor_get_first_child (actor);
|
||||
child != NULL;
|
||||
child = clutter_actor_get_next_sibling (child))
|
||||
{
|
||||
gfloat child_x, child_min, child_natural;
|
||||
|
||||
if (!clutter_actor_is_visible (child))
|
||||
continue;
|
||||
|
||||
child_x = clutter_actor_get_x (child);
|
||||
|
||||
clutter_actor_get_preferred_size (child,
|
||||
&child_min, NULL,
|
||||
&child_natural, NULL);
|
||||
|
||||
if (child_x + child_min > min_right)
|
||||
min_right = child_x + child_min;
|
||||
|
||||
if (child_x + child_natural > natural_right)
|
||||
natural_right = child_x + child_natural;
|
||||
}
|
||||
|
||||
if (min_width_p)
|
||||
*min_width_p = (float) min_right;
|
||||
|
||||
if (nat_width_p)
|
||||
*nat_width_p = (float) natural_right;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_fixed_layout_get_preferred_height (ClutterLayoutManager *manager,
|
||||
ClutterActor *container,
|
||||
gfloat for_width,
|
||||
gfloat *min_height_p,
|
||||
gfloat *nat_height_p)
|
||||
{
|
||||
ClutterActor *actor, *child;
|
||||
gdouble min_bottom;
|
||||
gdouble natural_bottom;
|
||||
|
||||
min_bottom = 0;
|
||||
natural_bottom = 0;
|
||||
|
||||
actor = CLUTTER_ACTOR (container);
|
||||
|
||||
for (child = clutter_actor_get_first_child (actor);
|
||||
child != NULL;
|
||||
child = clutter_actor_get_next_sibling (child))
|
||||
{
|
||||
gfloat child_y, child_min, child_natural;
|
||||
|
||||
if (!clutter_actor_is_visible (child))
|
||||
continue;
|
||||
|
||||
child_y = clutter_actor_get_y (child);
|
||||
|
||||
clutter_actor_get_preferred_size (child,
|
||||
NULL, &child_min,
|
||||
NULL, &child_natural);
|
||||
|
||||
if (child_y + child_min > min_bottom)
|
||||
min_bottom = child_y + child_min;
|
||||
|
||||
if (child_y + child_natural > natural_bottom)
|
||||
natural_bottom = child_y + child_natural;
|
||||
}
|
||||
|
||||
if (min_height_p)
|
||||
*min_height_p = (float) min_bottom;
|
||||
|
||||
if (nat_height_p)
|
||||
*nat_height_p = (float) natural_bottom;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_fixed_layout_allocate (ClutterLayoutManager *manager,
|
||||
ClutterActor *container,
|
||||
const ClutterActorBox *allocation)
|
||||
{
|
||||
ClutterActor *child;
|
||||
|
||||
for (child = clutter_actor_get_first_child (CLUTTER_ACTOR (container));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_fixed_layout_class_init (ClutterFixedLayoutClass *klass)
|
||||
{
|
||||
ClutterLayoutManagerClass *manager_class =
|
||||
CLUTTER_LAYOUT_MANAGER_CLASS (klass);
|
||||
|
||||
manager_class->get_preferred_width =
|
||||
clutter_fixed_layout_get_preferred_width;
|
||||
manager_class->get_preferred_height =
|
||||
clutter_fixed_layout_get_preferred_height;
|
||||
manager_class->allocate = clutter_fixed_layout_allocate;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_fixed_layout_init (ClutterFixedLayout *self)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_fixed_layout_new:
|
||||
*
|
||||
* Creates a new #ClutterFixedLayout
|
||||
*
|
||||
* Return value: the newly created #ClutterFixedLayout
|
||||
*/
|
||||
ClutterLayoutManager *
|
||||
clutter_fixed_layout_new (void)
|
||||
{
|
||||
return g_object_new (CLUTTER_TYPE_FIXED_LAYOUT, NULL);
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2009 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-layout-manager.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_FIXED_LAYOUT (clutter_fixed_layout_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterFixedLayout,
|
||||
clutter_fixed_layout,
|
||||
CLUTTER, FIXED_LAYOUT,
|
||||
ClutterLayoutManager)
|
||||
|
||||
struct _ClutterFixedLayoutClass
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterLayoutManagerClass parent_class;
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterLayoutManager *clutter_fixed_layout_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2011 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors:
|
||||
* Neil Roberts <neil@linux.intel.com>
|
||||
*/
|
||||
|
||||
/* This is an internal-only effect used to implement the
|
||||
'offscreen-redirect' property of ClutterActor. It doesn't actually
|
||||
need to do anything on top of the ClutterOffscreenEffect class so
|
||||
it only exists because that class is abstract */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-flatten-effect.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#include "clutter/clutter-actor-private.h"
|
||||
|
||||
struct _ClutterFlattenEffect
|
||||
{
|
||||
ClutterOffscreenEffect parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ClutterFlattenEffect,
|
||||
_clutter_flatten_effect,
|
||||
CLUTTER_TYPE_OFFSCREEN_EFFECT);
|
||||
|
||||
static void
|
||||
_clutter_flatten_effect_class_init (ClutterFlattenEffectClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
_clutter_flatten_effect_init (ClutterFlattenEffect *self)
|
||||
{
|
||||
}
|
||||
|
||||
ClutterEffect *
|
||||
_clutter_flatten_effect_new (void)
|
||||
{
|
||||
return g_object_new (CLUTTER_TYPE_FLATTEN_EFFECT, NULL);
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2011 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors:
|
||||
* Neil Roberts <neil@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "clutter/clutter-offscreen-effect.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_FLATTEN_EFFECT (_clutter_flatten_effect_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_FINAL_TYPE (ClutterFlattenEffect,
|
||||
_clutter_flatten_effect,
|
||||
CLUTTER,
|
||||
FLATTEN_EFFECT,
|
||||
ClutterOffscreenEffect)
|
||||
|
||||
|
||||
ClutterEffect *_clutter_flatten_effect_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user