Compare commits

..

1 Commits

Author SHA1 Message Date
Carlos Garnacho
18c85c9ffb backends: Compare gpu/crtc/output configurations before applying
This spares us from visible flickering whenever an unchanged configuration
is reapplied, eg. after lid open. The code in the X11 paths that did the
same comparisons has been removed in favor of the generic checks.

https://bugzilla.gnome.org/show_bug.cgi?id=791879
2019-09-04 16:29:04 +02:00
1677 changed files with 173865 additions and 168598 deletions

5
.gitignore vendored
View File

@@ -52,8 +52,12 @@ src/meta-dbus-idle-monitor.[ch]
src/meta-dbus-login1.[ch] src/meta-dbus-login1.[ch]
src/meta-dbus-remote-desktop.[ch] src/meta-dbus-remote-desktop.[ch]
src/meta-dbus-screen-cast.[ch] src/meta-dbus-screen-cast.[ch]
src/gtk-primary-selection-protocol.c
src/gtk-primary-selection-server-protocol.h
src/gtk-shell-protocol.c src/gtk-shell-protocol.c
src/gtk-shell-server-protocol.h 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*-protocol.c
src/pointer-gestures-unstable-v*-server-protocol.h src/pointer-gestures-unstable-v*-server-protocol.h
src/relative-pointer-unstable-v*-protocol.c src/relative-pointer-unstable-v*-protocol.c
@@ -99,4 +103,3 @@ doc/reference/meta.types
.dirstamp .dirstamp
**/tags.* **/tags.*
build/ build/
subprojects/sysprof/

View File

@@ -1,531 +1,79 @@
include: image: registry.gitlab.gnome.org/gnome/mutter/master:v2
- remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/34f4ade99434043f88e164933f570301fd18b125/templates/fedora.yml'
- remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/34f4ade99434043f88e164933f570301fd18b125/templates/ci-fairy.yml'
stages: stages:
- review - review
- prepare
- code-review
- build - build
- test - test
- analyze
- docs
- deploy
variables:
FDO_UPSTREAM_REPO: GNOME/mutter
.mutter.fedora@common:
variables:
FDO_DISTRIBUTION_VERSION: 36
BASE_TAG: '2022-09-01.0'
FDO_DISTRIBUTION_PACKAGES:
asciidoc
clang
gcovr
gdm
gnome-shell
mozjs91-devel
python3-dbusmock
sassc
uncrustify
xorg-x11-server-Xvfb
mesa-dri-drivers
xorg-x11-proto-devel
qemu-system-x86-core
busybox
gi-docgen
pkgconfig(libgcrypt)
pkgconfig(colord)
pkgconfig(lcms2)
FDO_DISTRIBUTION_EXEC: |
dnf install -y 'dnf-command(builddep)' &&
dnf builddep -y mutter --setopt=install_weak_deps=False &&
dnf builddep -y gnome-shell --setopt=install_weak_deps=False &&
dnf builddep -y wayland --setopt=install_weak_deps=False &&
dnf builddep -y wayland-protocols --setopt=install_weak_deps=False &&
dnf builddep -y kernel --setopt=install_weak_deps=False &&
./.gitlab-ci/install-meson-project.sh \
https://gitlab.gnome.org/GNOME/gjs.git \
1.73.1 . &&
./.gitlab-ci/install-meson-project.sh \
-Dvapi=false \
-Dgtk3=false \
-Dgtk4=false \
-Dgtk_doc=false \
-Dssh_agent=false \
-Dsystemd=disabled \
https://gitlab.gnome.org/GNOME/gcr.git \
3.90.0 . &&
./.gitlab-ci/install-meson-project.sh \
https://gitlab.freedesktop.org/wayland/wayland.git \
1.21.0 . &&
./.gitlab-ci/install-meson-project.sh \
https://gitlab.freedesktop.org/wayland/wayland-protocols.git \
1.26 . &&
./.gitlab-ci/install-meson-project.sh \
https://gitlab.gnome.org/jadahl/catch.git \
main . 29ad36e2b1d28ac9d8b2bc44af46296cb1db5d66 &&
rpm -e --nodeps gnome-bluetooth-libs-devel \
mutter mutter-devel \
gnome-shell &&
dnf clean all &&
if [[ x"$(uname -m )" = "xx86_64" ]] ; then
meson build -Dkvm_tests=true &&
ninja -C build src/tests/kvm/bzImage &&
mkdir -p /opt/mutter &&
cp build/src/tests/kvm/bzImage /opt/mutter/bzImage &&
dnf install -y python3-pyelftools &&
git clone https://github.com/jadahl/virtme.git &&
cd virtme &&
git checkout 87bcebe63f61e2a3ccd418b0903eab90113a47ae &&
./setup.py install --prefix=/usr &&
cd .. &&
rm -rf virtme
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
variables:
FDO_DISTRIBUTION_TAG: "x86_64-${BASE_TAG}"
.mutter.fedora@aarch64:
extends: .mutter.fedora@common
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'
check-commit-log: check-commit-log:
extends:
- .fdo.ci-fairy
stage: review stage: review
variables: variables:
GIT_DEPTH: "100" GIT_DEPTH: "100"
script: script:
- if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ; - ./.gitlab-ci/check-commit-log.sh
then only:
ci-fairy check-commits --junit-xml=commit-message-junit-report.xml ; - merge_requests
else
echo "Not a merge request" ;
fi
artifacts:
expire_in: 1 week
paths:
- commit-message-junit-report.xml
reports:
junit: commit-message-junit-report.xml
rules:
- !reference [.pipeline-guard, rules]
check-merge-request: build-mutter:
extends:
- .fdo.ci-fairy
stage: review
variables:
GIT_STRATEGY: none
script:
- if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ;
then
ci-fairy check-merge-request --require-allow-collaboration --junit-xml=check-merge-request-report.xml ;
else
echo "Not a merge request" ;
fi
artifacts:
expire_in: 1 week
paths:
- check-merge-request-report.xml
reports:
junit: check-merge-request-report.xml
rules:
- !reference [.pipeline-guard, rules]
build-fedora-container@x86_64:
extends:
- .fdo.container-build@fedora@x86_64
- .mutter.fedora@x86_64
stage: prepare
needs:
- check-commit-log
- check-merge-request
variables:
GIT_STRATEGY: none
build-fedora-container@aarch64:
extends:
- .fdo.container-build@fedora@aarch64
- .mutter.fedora@aarch64
stage: prepare
needs:
- check-commit-log
- check-merge-request
variables:
GIT_STRATEGY: none
check-code-style:
extends:
- .fdo.distribution-image@fedora
- .mutter.fedora@x86_64
stage: code-review
needs:
- build-fedora-container@x86_64
script:
- if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ;
then
git remote add target $CI_MERGE_REQUEST_PROJECT_URL.git ;
git fetch target $CI_MERGE_REQUEST_TARGET_BRANCH_NAME ;
export common_parent_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "target/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME") <(git rev-list --first-parent HEAD) | head -1) ;
python3 -u ./check-style.py --dry-run --sha $common_parent_sha ;
else
echo "Not a merge request" ;
fi
allow_failure: true
.build-mutter-base:
variables:
BASE_MESON_OPTIONS:
-Degl_device=true
-Dwayland_eglstream=true
-Dcatch=true
.build-mutter:
extends:
- .fdo.distribution-image@fedora
- .build-mutter-base
stage: build stage: build
script: script:
- meson . build - meson . build -Dbuildtype=debugoptimized -Degl_device=true -Dwayland_eglstream=true --werror --prefix /usr
--prefix /usr - ninja -C build
--werror - ninja -C build install
--fatal-meson-warnings
--warnlevel 2
-Dbuildtype=debugoptimized
-Db_coverage=true
$BASE_MESON_OPTIONS
$EXTRA_MESON_OPTIONS
- meson compile -C build
- meson install -C build
artifacts: artifacts:
expire_in: 1 day expire_in: 1 day
paths: paths:
- build - build
only:
- merge_requests
- /^.*$/
build-mutter@x86_64: build-without-native-backend:
variables:
EXTRA_MESON_OPTIONS:
-Dkvm_tests=true
-Dkvm_kernel_image=/opt/mutter/bzImage
extends:
- .build-mutter
- .mutter.fedora@x86_64
needs:
- build-fedora-container@x86_64
build-mutter@aarch64:
extends:
- .build-mutter
- .mutter.fedora@aarch64
needs:
- build-fedora-container@aarch64
build-without-opengl-and-glx@x86_64:
extends:
- .fdo.distribution-image@fedora
- .mutter.fedora@x86_64
stage: build stage: build
needs:
- build-fedora-container@x86_64
script: script:
- meson . build --werror --prefix /usr - meson . build -Dbuildtype=debugoptimized -Dnative_backend=false -Dudev=false --werror --prefix /usr
-Dbuildtype=debugoptimized - ninja -C build
-Dopengl=false - ninja -C build install
-Dglx=false
-Degl_device=true
-Dwayland_eglstream=true
- meson compile -C build
- meson install -C build
artifacts: artifacts:
expire_in: 1 day
paths: paths:
- build/meson-logs - build
only:
- merge_requests
- /^.*$/
build-without-native-backend-and-wayland@x86_64: test-mutter:
extends: stage: test
- .fdo.distribution-image@fedora dependencies:
- .mutter.fedora@x86_64 - build-mutter
stage: build
needs:
- build-fedora-container@x86_64
script:
- meson . build --werror --prefix /usr
-Dbuildtype=debugoptimized
-Dnative_backend=false
-Dudev=false
-Dwayland=false
-Dcore_tests=false
-Dnative_tests=false
- meson compile -C build
- meson install -C build
artifacts:
paths:
- build/meson-logs
.test-setup: &test-setup
variables: variables:
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir" XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
GSETTINGS_SCHEMA_DIR: "$CI_PROJECT_DIR/build/data" 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" G_SLICE: "always-malloc"
MALLOC_CHECK_: "3" MALLOC_CHECK_: "3"
NO_AT_BRIDGE: "1" NO_AT_BRIDGE: "1"
before_script: MALLOC_PERTURB_: "123"
# Disable e.g. audio support to not dead lock screen cast tests script:
- dconf update
- mkdir -m 700 $XDG_RUNTIME_DIR - mkdir -m 700 $XDG_RUNTIME_DIR
- pipewire & sleep 2
.test-mutter-base:
extends:
- .fdo.distribution-image@fedora
<<: *test-setup
stage: test
after_script:
- pushd build
- gcovr --root=..
--filter='\.\./src/' --filter='\.\./clutter/' --filter='\.\./cogl/'
--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:
- .fdo.distribution-image@fedora
- .test-mutter-base
script:
- glib-compile-schemas $GSETTINGS_SCHEMA_DIR - glib-compile-schemas $GSETTINGS_SCHEMA_DIR
- dbus-run-session -- xvfb-run -a -s "$XVFB_SERVER_ARGS" - >
./.gitlab-ci/run-meson.sh test -C build dbus-run-session -- xvfb-run -s '+iglx -noreset'
--no-suite 'mutter/kvm' meson test -C build --no-rebuild -t 10 --verbose --no-stdsplit --print-errorlogs --wrap catchsegv
--no-rebuild only:
--timeout-multiplier 10 - merge_requests
artifacts: - /^.*$/
reports:
junit: "build/meson-logs/testlog.junit.xml"
test-mutter@x86_64: can-build-gnome-shell:
extends:
- .test-mutter
- .mutter.fedora@x86_64
tags:
- asan
needs:
- build-mutter@x86_64
test-mutter-kvm@x86_64:
extends:
- .test-mutter-base
- .mutter.fedora@x86_64
tags:
- kvm
script:
meson test -C build
--no-rebuild
--timeout-multiplier 10
--setup plain
--suite 'mutter/kvm'
needs:
- build-mutter@x86_64
artifacts:
reports:
junit: "build/meson-logs/testlog-plain.junit.xml"
test-mutter@aarch64:
extends:
- .test-mutter
- .mutter.fedora@aarch64
tags:
- asan-aarch64
needs:
- build-mutter@aarch64
coverage:
extends:
- .fdo.distribution-image@fedora
- .mutter.fedora@x86_64
stage: analyze
script:
- mkdir coveragereport
- gcovr --add-tracefile 'coverage-*.json'
--html-details --print-summary --output coveragereport/index.html
artifacts:
paths:
- coveragereport
coverage: '/^lines: (\d+\.\d+\%)/'
needs:
- test-mutter@x86_64
- test-mutter@aarch64
- test-mutter-kvm@x86_64
can-build-gnome-shell@x86_64:
extends:
- .fdo.distribution-image@fedora
- .mutter.fedora@x86_64
stage: test stage: test
needs: dependencies:
- build-mutter@x86_64 - build-mutter
before_script: before_script:
- meson install --no-rebuild -C build - meson install --no-rebuild -C build
script: script:
- .gitlab-ci/checkout-gnome-shell.sh - .gitlab-ci/checkout-gnome-shell.sh
- meson gnome-shell gnome-shell/build --prefix /usr -Dman=false - meson gnome-shell gnome-shell/build --prefix /usr -Dman=false
- meson install -C gnome-shell/build - ninja -C gnome-shell/build install
only:
test-mutter-coverity: - merge_requests
rules: - /^.*$/
- if: '$CI_PIPELINE_SOURCE == "schedule" && $MUTTER_SCHEDULED_JOB == "coverity"'
when: always
- if: '$CI_COMMIT_BRANCH'
when: 'manual'
extends:
- .fdo.distribution-image@fedora
- .mutter.fedora@x86_64
needs:
- build-fedora-container@x86_64
stage: analyze
allow_failure: true
script:
- .gitlab-ci/download-coverity-tarball.sh
- CC=clang meson coverity-build -Dprofiler=false
- ./coverity/cov-analysis-linux64-*/bin/cov-build --dir cov-int meson compile -C coverity-build
- tar czf cov-int.tar.gz cov-int
- curl https://scan.coverity.com/builds?project=mutter
--form token=$COVERITY_TOKEN --form email=carlosg@gnome.org
--form file=@cov-int.tar.gz --form version="`git describe --tags`"
--form description="GitLab CI build"
cache:
key: coverity-tarball
paths:
- coverity
dist-mutter:
extends:
- .fdo.distribution-image@fedora
- .mutter.fedora@x86_64
- .build-mutter-base
<<: *test-setup
stage: deploy
needs:
- build-fedora-container@x86_64
script:
- meson . build --werror --prefix /usr
-Dbuildtype=debugoptimized
- glib-compile-schemas $GSETTINGS_SCHEMA_DIR
- dbus-run-session -- xvfb-run -a -s "$XVFB_SERVER_ARGS"
./.gitlab-ci/run-meson.sh dist -C build
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
changes:
- "**/meson.build"
- meson/*
dist-mutter-tarball:
extends: dist-mutter
artifacts:
expose_as: 'Get tarball here'
paths:
- build/meson-dist/$CI_PROJECT_NAME-$CI_COMMIT_TAG.tar.xz
rules:
- if: '$CI_COMMIT_TAG'
reference:
extends:
- .fdo.distribution-image@fedora
- .mutter.fedora@x86_64
stage: docs
needs:
- job: build-fedora-container@x86_64
artifacts: false
script:
- meson . build --werror -Ddocs=true -Dtests=false
- ninja -C build
- mkdir references
- mv build/doc/reference/{cally/cally,clutter/clutter,cogl/cogl,cogl-pango/cogl-pango,meta/meta} references/
artifacts:
expire_in: 1 week
paths:
- references
pages:
stage: deploy
needs: ['reference']
script:
- mv references public/
artifacts:
paths:
- public
rules:
- if: ($CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH && $CI_PROJECT_NAMESPACE == "GNOME")

40
.gitlab-ci/Dockerfile Normal file
View File

@@ -0,0 +1,40 @@
# Rebuild and push with
#
# cd .gitlab-ci/
# docker build --no-cache -t registry.gitlab.gnome.org/gnome/mutter/master:v2 .
# docker push registry.gitlab.gnome.org/gnome/mutter/master:v2
#
FROM fedora:30
RUN dnf -y update && dnf -y upgrade && \
dnf install -y 'dnf-command(builddep)' && \
dnf install -y 'dnf-command(copr)' && \
dnf copr enable -y fmuellner/gnome-shell-ci && \
dnf copr enable -y jadahl/mutter-ci && \
dnf copr enable -y hergertme/sysprof-3 && \
dnf -y update && dnf -y upgrade && \
dnf builddep -y mutter && \
# Until Fedora catches up with meson build-deps
dnf install -y meson xorg-x11-server-Xorg gnome-settings-daemon-devel egl-wayland-devel xorg-x11-server-Xwayland && \
# Until Fedora catches up with mesa bug fixes
dnf upgrade -y mesa-dri-drivers mesa-libEGL && \
# For running unit tests
dnf install -y xorg-x11-server-Xvfb mesa-dri-drivers dbus dbus-x11 '*/xvfb-run' gdm-lib accountsservice-libs && \
dnf install -y sysprof-devel && \
dnf install -y intltool redhat-rpm-config make && \
# GNOME Shell
dnf builddep -y gnome-shell --setopt=install_weak_deps=False && \
# New dep this cycle
dnf install -y 'pkgconfig(gnome-autoar-0)' && \
dnf remove -y gnome-bluetooth-libs-devel dbus-glib-devel upower-devel python3-devel && \
dnf remove -y --noautoremove mutter mutter-devel && \
dnf clean all

57
.gitlab-ci/check-commit-log.sh Executable file
View File

@@ -0,0 +1,57 @@
#!/usr/bin/env bash
if [ -z "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
echo Cannot review non-merge request
exit 1
fi
git fetch $CI_MERGE_REQUEST_PROJECT_URL.git $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
branch_point=$(git merge-base HEAD FETCH_HEAD)
commits=$(git log --format='format:%H' $branch_point..$CI_COMMIT_SHA)
if [ -z "$commits" ]; then
echo Commit range empty
exit 1
fi
function commit_message_has_url() {
commit=$1
commit_message=$(git show -s --format='format:%b' $commit)
echo "$commit_message" | grep -qe "\($CI_MERGE_REQUEST_PROJECT_URL/\(issues\|merge_requests\)/[0-9]\+\|https://bugzilla.gnome.org/show_bug.cgi?id=[0-9]\+\)"
return $?
}
function commit_message_subject_is_compliant() {
commit=$1
commit_message_subject=$(git show -s --format='format:%s' $commit)
if echo "$commit_message_subject" | grep -qe "\(^meta-\|^Meta\)"; then
echo " - message subject should not be prefixed with 'meta-' or 'Meta'"
return 1
fi
if echo "$commit_message_subject" | grep -qe "\.[ch]:"; then
echo " - message subject prefix should not include .c, .h, etc."
return 1
fi
return 0
}
for commit in $commits; do
commit_short=$(echo $commit | cut -c -8)
if ! commit_message_has_url $commit; then
echo "Missing merge request or issue URL on commit $commit_short"
exit 1
fi
errors=$(commit_message_subject_is_compliant $commit)
if [ $? != 0 ]; then
echo "Commit message for $commit_short is not compliant:"
echo "$errors"
exit 1
fi
done

View File

@@ -1,19 +1,12 @@
#!/usr/bin/bash #!/usr/bin/bash
fetch() { mutter_branch=$(git describe --contains --all HEAD)
local remote=$1
local ref=$2
git fetch --quiet --depth=1 $remote $ref 2>/dev/null
}
gnome_shell_target= gnome_shell_target=
echo -n Cloning into gnome-shell ... git clone https://gitlab.gnome.org/GNOME/gnome-shell.git
if git clone --quiet --depth=1 https://gitlab.gnome.org/GNOME/gnome-shell.git; then
echo \ done if [ $? -ne 0 ]; then
else echo Checkout failed
echo \ failed
exit 1 exit 1
fi fi
@@ -23,33 +16,20 @@ if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
merge_request_remote=${CI_MERGE_REQUEST_SOURCE_PROJECT_URL//mutter/gnome-shell} merge_request_remote=${CI_MERGE_REQUEST_SOURCE_PROJECT_URL//mutter/gnome-shell}
merge_request_branch=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME merge_request_branch=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
echo -n Looking for $merge_request_branch on remote ... echo Looking for $merge_request_branch on remote ...
if fetch $merge_request_remote $merge_request_branch; then if git fetch -q $merge_request_remote $merge_request_branch 2>/dev/null; then
echo \ found
gnome_shell_target=FETCH_HEAD gnome_shell_target=FETCH_HEAD
else else
echo \ not found gnome_shell_target=origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
echo -n Looking for $CI_MERGE_REQUEST_TARGET_BRANCH_NAME instead ...
if fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME; then
echo \ found
gnome_shell_target=FETCH_HEAD
else
echo \ not found
fi
fi
fi
if [ -z "$gnome_shell_target" ]; then
echo -n Looking for $CI_COMMIT_REF_NAME on remote ...
if fetch origin $CI_COMMIT_REF_NAME; then
echo \ found
gnome_shell_target=FETCH_HEAD
else
echo \ not found
gnome_shell_target=HEAD
echo Using $gnome_shell_target instead echo Using $gnome_shell_target instead
fi fi
fi fi
if [ -z "$gnome_shell_target" ]; then
gnome_shell_target=$(git branch -r -l origin/$mutter_branch)
gnome_shell_target=${gnome_shell_target:-$(git branch -r -l ${mutter_branch#remotes/})}
gnome_shell_target=${gnome_shell_target:-origin/master}
echo Using $gnome_shell_target instead
fi
git checkout -q $gnome_shell_target git checkout -q $gnome_shell_target

View File

@@ -1,19 +0,0 @@
patterns:
deny:
- regex: '^$CI_MERGE_REQUEST_PROJECT_URL/(-/)?merge_requests/$CI_MERGE_REQUEST_IID$'
message: Commit message must not contain a link to its own merge request
- regex: '^(meta-|Meta)'
message: Commit message subject should not be prefixed with 'meta-' or 'Meta'
where: subject
- regex: '^(clutter-|Clutter)'
message: Commit message subject should not be prefixed with 'clutter-' or 'Clutter', use 'clutter/' instead
where: subject
- regex: '^(cogl-|Cogl)'
message: Commit message subject should not be prefixed with 'cogl-' or 'Cogl', use 'cogl/' instead
where: subject
- regex: '^[^:]+: [a-z]'
message: "Commit message subject should be properly Capitalized. E.g. 'window: Marginalize extradicity'"
where: subject
- regex: '^\S*\.[ch]:'
message: Commit message subject prefix should not include .c, .h, etc.
where: subject

View File

@@ -1,38 +0,0 @@
#!/usr/bin/bash
# We need a coverity token to fetch the tarball
if [ -x $COVERITY_TOKEN ]
then
echo "No coverity token. Run this job from a protected branch."
exit -1
fi
mkdir -p coverity
# Download and check MD5 first
curl https://scan.coverity.com/download/linux64 \
--data "token=$COVERITY_TOKEN&project=mutter&md5=1" \
--output /tmp/coverity_tool.md5
diff /tmp/coverity_tool.md5 coverity/coverity_tool.md5 >/dev/null 2>&1
if [ $? -eq 0 -a -d coverity/cov-analysis* ]
then
echo "Coverity tarball is up-to-date"
exit 0
fi
# Download and extract coverity tarball
curl https://scan.coverity.com/download/linux64 \
--data "token=$COVERITY_TOKEN&project=mutter" \
--output /tmp/coverity_tool.tgz
rm -rf ./coverity/cov-analysis*
tar zxf /tmp/coverity_tool.tgz -C coverity/
if [ $? -eq 0 ]
then
mv /tmp/coverity_tool.md5 coverity/
fi
rm /tmp/coverity_tool.tgz

View File

@@ -1,39 +0,0 @@
#!/bin/bash
set -e
if [[ $# -lt 3 ]]; then
echo Usage: $0 [options] [repo-url] [commit] [subdir]
echo Options:
echo -Dkey=val
exit 1
fi
MESON_OPTIONS=()
while [[ $1 =~ ^-D ]]; do
MESON_OPTIONS+=( "$1" )
shift
done
REPO_URL="$1"
TAG_OR_BRANCH="$2"
SUBDIR="$3"
COMMIT="$4"
REPO_DIR="$(basename ${REPO_URL%.git})"
git clone --depth 1 "$REPO_URL" -b "$TAG_OR_BRANCH"
pushd "$REPO_DIR"
pushd "$SUBDIR"
if [ ! -z "$COMMIT" ]; then
git fetch origin "$COMMIT"
git checkout "$COMMIT"
fi
meson --prefix=/usr _build "${MESON_OPTIONS[@]}"
meson install -C _build
popd
popd
rm -rf "$REPO_DIR"

View File

@@ -1,8 +0,0 @@
#!/usr/bin/bash
set -e
wireplumber &
sleep 1
meson "$@"

View File

@@ -1,55 +0,0 @@
<!--
Please read https://wiki.gnome.org/Community/GettingInTouch/BugReportingGuidelines
first to ensure that you create a clear and specific issue.
-->
### Affected version
<!--
Provide at least the following information:
* Your OS and version
* Affected Mutter version
* Does this issue appear in XOrg and/or Wayland
-->
### Bug summary
<!--
Provide a short summary of the bug you encountered.
-->
### Steps to reproduce
<!--
1. Step one
2. Step two
3. ...
-->
### What happened
<!--
What did Mutter do that was unexpected?
-->
### What did you expect to happen
<!--
What did you expect Mutter to do?
-->
### Relevant logs, screenshots, screencasts etc.
<!--
If you have further information, such as technical documentation, logs,
screenshots or screencasts related, please provide them here.
If the bug is a crash, please obtain a stack trace with installed debug
symbols (at least for GNOME Shell and Mutter) and attach it to
this issue following the instructions on
https://wiki.gnome.org/Community/GettingInTouch/Bugzilla/GettingTraces.
-->
<!-- Do not remove the following line. -->
/label ~"1. Bug"

View File

@@ -1,30 +0,0 @@
<!--
Please read https://wiki.gnome.org/Community/GettingInTouch/BugReportingGuidelines
first to ensure that you create a clear and specific issue.
-->
### Feature summary
<!--
Describe what you would like to be able to do with Mutter
that you currently cannot do.
-->
### How would you like it to work
<!--
If you can think of a way Mutter might be able to do this,
let us know here.
-->
### Relevant links, screenshots, screencasts etc.
<!--
If you have further information, such as technical documentation,
code, mockups or a similar feature in another window managers,
please provide them here.
-->
<!-- Do not remove the following line. -->
/label ~"1. Feature"

View File

@@ -1,286 +0,0 @@
# Style
The coding style used is primarily the GNU flavor of the [GNOME coding
style][gnome-coding-style], with some additions described below.
## General
* Use this code style on new code. When changing old code with a different
code style, feel free to also adjust it to use this code style.
* Use regular C types and `stdint.h` types instead of GLib fundamental
types, except for `gboolean`, and `guint`/`gulong` for GSource IDs and
signal handler IDs. That means e.g. `uint64_t` instead of `guint64`, `int`
instead of `gint`, `unsigned int` instead of `guint` if unsignedness
is of importance, `uint8_t` instead of `guchar`, and so on.
* Try to to limit line length to 80 characters, although it's not a
strict limit.
* Usage of `g_autofree` and `g_autoptr` is encouraged. The style to use is
```c
g_autofree char *text = NULL;
g_autoptr (MetaSomeThing) thing = NULL;
text = g_strdup_printf ("The text: %d", a_number);
thing = g_object_new (META_TYPE_SOME_THING,
"text", text,
NULL);
thinger_use_thing (rocket, thing);
```
* Declare variables at the top of the block they are used, but avoid
non-trivial logic among variable declarations. Non-trivial logic can be
getting a pointer that may be `NULL`, any kind of math, or anything
that may have side effects.
* Instead of boolean arguments in functions, prefer enums or flags when
they're more expressive. The naming convention for flags is
```c
typedef _MetaSomeThingFlags
{
META_SOME_THING_FLAG_NONE = 0,
META_SOME_THING_FLAG_ALTER_REALITY = 1 << 0,
META_SOME_THING_FLAG_MANIPULATE_PERCEPTION = 1 << 1,
} MetaSomeThingFlags;
```
* Use `g_new0 ()` etc. instead of `g_slice_new0 ()`.
* Initialize and assign floating point variables (i.e. `float` or
`double`) using the form `floating_point = 3.14159` or `ratio = 2.0`.
## Header (.h) files
* The return type and `*` are separated by a space.
* Function name starts one space after the last `*`.
* Parenthesis comes one space after the function name.
As an example, this is how functions in a header file should look like:
```c
gboolean meta_udev_is_drm_device (MetaUdev *udev,
GUdevDevice *device);
GList * meta_udev_list_drm_devices (MetaUdev *udev,
GError **error);
MetaUdev * meta_udev_new (MetaBackendNative *backend_native);
```
## Source code
Keep functions in the following order in source files:
1. GPL header
2. Enums
3. Structures
4. Function prototypes
5. `G_DEFINE_TYPE()`
6. Static variables
7. Auxiliary functions
8. Callbacks
9. Interface implementations
10. Parent vfunc overrides
11. class_init and init
12. Public API
### Structures
Each structure field has a space after their type name. Structure fields aren't
aligned. For example:
```c
struct _MetaFooBar
{
MetaFoo parent;
MetaBar *bar;
MetaSomething *something;
};
```
### Function Prototypes
Function prototypes must be formatted just like in header files.
### Overrides
When overriding parent class vfuncs, or implementing an interface, vfunc
overrides should be named as a composition of the current class prefix,
followed by the vfunc name. For example:
```c
static void
meta_bar_spawn_unicorn (MetaParent *parent)
{
/* ... */
}
static void
meta_bar_dispose (GObject *object)
{
/* ... */
}
static void
meta_bar_finalize (GObject *object)
{
/* ... */
}
static void
meta_bar_class_init (MetaBarClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
MetaParentClass *parent_class = META_PARENT_CLASS (klass);
object_class->dispose = meta_bar_dispose;
object_class->finalize = meta_bar_finalize;
parent_class->spawn_unicorn = meta_bar_spawn_unicorn;
}
```
### Interface Implementations
When implementing interfaces, two groups of functions are involved: the init
function, and the overrides.
The interface init function is named after the interface type in snake case,
followed by the `_iface_init` suffix. For example:
```c
static void meta_foo_iface_init (MetaFooInterface *foo_iface);
G_DEFINE_TYPE_WITH_CODE (MetaBar, meta_bar, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (META_TYPE_FOO,
meta_foo_iface_init));
```
Then, when implementing each vfunc of the interface, follow the same pattern
of the [Overrides](###Overrides) section. Here's an example:
```c
static void
meta_bar_do_something (MetaFoo *foo)
{
/* ... */
}
static void
meta_foo_iface_init (MetaFooInterface *foo_iface)
{
foo_iface->do_something = meta_bar_do_something;
}
```
### Auxiliary Functions
Auxiliary functions are above every other functions to minimize the number of
function prototypes in the file. These functions often grow when factoring out
the same code between two or more functions:
```c
static void
do_something_on_data (Foo *data,
Bar *bar)
{
/* ... */
}
static void
random_function (Foo *foo)
{
do_something_on_data (foo, bar);
}
static void
another_random_function (Foo *foo)
{
do_something_on_data (foo, bar);
}
```
Sometimes, however, auxiliary functions are created to break down otherwise
large functions - in this case, it is appropriate to keep these auxiliary
functions close to the function they are tightly related to.
Auxiliary function names must have a verb in the imperative form, and should
always perform an action over something. They usually don't have the class
prefix (`meta_`, `clutter_`, or `cogl_`). For example:
```c
static void
do_something_on_data (Foo *data,
Bar *bar)
{
/* ... */
}
```
Exceptionally, when converting between types, auxiliary function names may
have the class prefix to this rule. For example:
```c
static MetaFoo *
meta_foo_from_bar (Bar *bar)
{
/* ... */
}
```
### Callback Functions
Callback function names should have the name of the action in imperative
form. They don't have any prefix, but have a `_func` suffix. For example:
```c
static void
filter_something_func (Foo *foo,
Bar *bar,
gpointer user_data)
{
/* ... */
}
```
### Signal Callbacks
Signal callbacks generally have the signal name. They should be prefixed with
`on_`, or suffixed with `_cb`, but not both. For example:
```c
static void
on_realize (ClutterActor *actor,
gpointer user_data)
{
/* ... */
}
static void
destroy_cb (ClutterActor *actor,
gpointer user_data)
{
/* ... */
}
```
When the callback is named after the object that generated it, and the signal,
then passive voice is used. For example:
```c
static void
click_action_clicked_cb (ClutterClickAction *click_action,
ClutterActor *actor,
gpointer user_data)
{
/* ... */
}
```
[gnome-coding-style]: https://developer.gnome.org/documentation/guidelines/programming/coding-style.html

1141
NEWS

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,7 @@ window compositing, focus tracking, workspace management, keybindings and
monitor configuration. monitor configuration.
Internally it uses a fork of Cogl, a hardware acceleration abstraction library 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 used to simplify usage of OpenGL pipelines, as well as a fork af Clutter, a
scene graph and user interface toolkit. scene graph and user interface toolkit.
Mutter is used by, for example, GNOME Shell, the GNOME core user interface, and Mutter is used by, for example, GNOME Shell, the GNOME core user interface, and
@@ -26,41 +26,15 @@ debugging purposes.
To contribute, open merge requests at https://gitlab.gnome.org/GNOME/mutter. To contribute, open merge requests at https://gitlab.gnome.org/GNOME/mutter.
It can be useful to look at the documentation available at the The coding style used is primarily the GNU flavor of the [GNOME coding
[Wiki](https://gitlab.gnome.org/GNOME/mutter/-/wikis/home). style](https://developer.gnome.org/programming-guidelines/stable/c-coding-style.html.en)
with some minor additions such as preferring `stdint.h` types over GLib
The API documentation is available at: fundamental types, and a soft 80 character line limit. However, in general,
- Meta: <https://gnome.pages.gitlab.gnome.org/mutter/meta/> look at the file you're editing for inspiration.
- Clutter: <https://gnome.pages.gitlab.gnome.org/mutter/clutter/>
- Cally: <https://gnome.pages.gitlab.gnome.org/mutter/cally/>
- Cogl: <https://gnome.pages.gitlab.gnome.org/mutter/cogl/>
- CoglPango: <https://gnome.pages.gitlab.gnome.org/mutter/cogl-pango/>
## Coding style and conventions
See [HACKING.md](./HACKING.md).
## Git messages
Commit messages should follow the [GNOME commit message Commit messages should follow the [GNOME commit message
guidelines](https://wiki.gnome.org/Git/CommitMessages). We require an URL guidelines](https://wiki.gnome.org/Git/CommitMessages). We require an URL
to either an issue or a merge request in each commit. Try to always prefix to either an issue or a merge request in each commit.
commit subjects with a relevant topic, such as `compositor:` or
`clutter/actor:`, and it's always better to write too much in the commit
message body than too little.
## Default branch
The default development branch is `main`. If you still have a local
checkout under the old name, use:
```sh
git checkout master
git branch -m master main
git fetch
git branch --unset-upstream
git branch -u origin/main
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
```
## License ## License

View File

@@ -1,138 +0,0 @@
#!/bin/env python3
import argparse
import os
import re
import subprocess
import sys
import tempfile
# Path relative to this script
uncrustify_cfg = 'tools/uncrustify.cfg'
def run_diff(sha):
proc = subprocess.Popen(["git", "diff", "-U0", "--function-context", sha, "HEAD"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
files = proc.stdout.read().strip().decode('utf-8')
return files.split('\n')
def find_chunks(diff):
file_entry_re = re.compile('^\+\+\+ b/(.*)$')
diff_chunk_re = re.compile('^@@ -\d+,\d+ \+(\d+),(\d+)')
file = None
chunks = []
for line in diff:
match = file_entry_re.match(line)
if match:
file = match.group(1)
match = diff_chunk_re.match(line)
if match:
start = int(match.group(1))
len = int(match.group(2))
end = start + len
if len > 0 and (file.endswith('.c') or file.endswith('.h') or file.endswith('.vala')):
chunks.append({ 'file': file, 'start': start, 'end': end })
return chunks
def reformat_chunks(chunks, rewrite):
# Creates temp file with INDENT-ON/OFF comments
def create_temp_file(file, start, end):
with open(file) as f:
tmp = tempfile.NamedTemporaryFile()
tmp.write(b'/** *INDENT-OFF* **/\n')
for i, line in enumerate(f):
if i == start - 2:
tmp.write(b'/** *INDENT-ON* **/\n')
tmp.write(bytes(line, 'utf-8'))
if i == end - 2:
tmp.write(b'/** *INDENT-OFF* **/\n')
tmp.seek(0)
return tmp
# Removes uncrustify INDENT-ON/OFF helper comments
def remove_indent_comments(output):
tmp = tempfile.NamedTemporaryFile()
for line in output:
if line != b'/** *INDENT-OFF* **/\n' and line != b'/** *INDENT-ON* **/\n':
tmp.write(line)
tmp.seek(0)
return tmp
changed = None
for chunk in chunks:
# Add INDENT-ON/OFF comments
tmp = create_temp_file(chunk['file'], chunk['start'], chunk['end'])
# uncrustify chunk
proc = subprocess.Popen(["uncrustify", "-c", uncrustify_cfg, "-f", tmp.name], stdout=subprocess.PIPE)
reindented = proc.stdout.readlines()
proc.wait()
if proc.returncode != 0:
continue
tmp.close()
# Remove INDENT-ON/OFF comments
formatted = remove_indent_comments(reindented)
if dry_run is True:
# Show changes
proc = subprocess.Popen(["diff", "-up", "--color=always", chunk['file'], formatted.name], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
diff = proc.stdout.read().decode('utf-8')
if diff != '':
output = re.sub('\t', '\t', diff)
print(output)
changed = True
else:
# Apply changes
diff = subprocess.Popen(["diff", "-up", chunk['file'], formatted.name], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
patch = subprocess.Popen(["patch", chunk['file']], stdin=diff.stdout)
diff.stdout.close()
patch.communicate()
formatted.close()
return changed
parser = argparse.ArgumentParser(description='Check code style.')
parser.add_argument('--sha', metavar='SHA', type=str,
help='SHA for the commit to compare HEAD with')
parser.add_argument('--dry-run', '-d', type=bool,
action=argparse.BooleanOptionalAction,
help='Only print changes to stdout, do not change code')
parser.add_argument('--rewrite', '-r', type=bool,
action=argparse.BooleanOptionalAction,
help='Whether to amend the result to the last commit (e.g. \'git rebase --exec "%(prog)s -r"\')')
# Change CWD to script location, necessary for always locating the configuration file
os.chdir(os.path.dirname(os.path.abspath(sys.argv[0])))
args = parser.parse_args()
sha = args.sha or 'HEAD^'
rewrite = args.rewrite
dry_run = args.dry_run
diff = run_diff(sha)
chunks = find_chunks(diff)
changed = reformat_chunks(chunks, rewrite)
if dry_run is not True and rewrite is True:
proc = subprocess.Popen(["git", "commit", "--all", "--amend", "-C", "HEAD"], stdout=subprocess.DEVNULL)
os._exit(0)
elif dry_run is True and changed is True:
print ("\nIssue the following command in your local tree to apply the suggested changes (needs uncrustify installed):\n\n $ git rebase origin/main --exec \"./check-style.py -r\" \n")
os._exit(-1)
os._exit(0)

View File

@@ -28,7 +28,7 @@
#include "cally-actor.h" #include "cally-actor.h"
/* /*
* Auxiliary define, in order to get the clutter actor from the AtkObject using * Auxiliar define, in order to get the clutter actor from the AtkObject using
* AtkGObject methods * AtkGObject methods
* *
*/ */

View File

@@ -23,11 +23,12 @@
*/ */
/** /**
* CallyActor: * SECTION:cally-actor
* @Title: CallyActor
* @short_description: Implementation of the ATK interfaces for #ClutterActor
* @see_also: #ClutterActor
* *
* Implementation of the ATK interfaces for [class@Clutter.Actor] * #CallyActor implements the required ATK interfaces of #ClutterActor
*
* #CallyActor implements the required ATK interfaces of [class@Clutter.Actor]
* exposing the common elements on each actor (position, extents, etc). * exposing the common elements on each actor (position, extents, etc).
*/ */
@@ -71,7 +72,9 @@
#include <glib.h> #include <glib.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include "clutter/clutter-actor-private.h" #ifdef CLUTTER_WINDOWING_X11
#include <clutter/x11/clutter-x11.h>
#endif
#include <math.h> #include <math.h>
@@ -193,6 +196,8 @@ G_DEFINE_TYPE_WITH_CODE (CallyActor,
* Creates a new #CallyActor for the given @actor * Creates a new #CallyActor for the given @actor
* *
* Return value: the newly created #AtkObject * Return value: the newly created #AtkObject
*
* Since: 1.4
*/ */
AtkObject * AtkObject *
cally_actor_new (ClutterActor *actor) cally_actor_new (ClutterActor *actor)
@@ -305,7 +310,11 @@ cally_actor_finalize (GObject *obj)
_cally_actor_clean_action_list (cally_actor); _cally_actor_clean_action_list (cally_actor);
g_clear_handle_id (&priv->action_idle_handler, g_source_remove); if (priv->action_idle_handler)
{
g_source_remove (priv->action_idle_handler);
priv->action_idle_handler = 0;
}
if (priv->action_queue) if (priv->action_queue)
{ {
@@ -595,11 +604,10 @@ cally_actor_real_remove_actor (ClutterActor *container,
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0); g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0);
atk_parent = ATK_OBJECT (data); atk_parent = ATK_OBJECT (data);
if (clutter_actor_has_accessible (actor))
{
atk_child = clutter_actor_get_accessible (actor); atk_child = clutter_actor_get_accessible (actor);
if (atk_child)
{
g_value_init (&values.old_value, G_TYPE_POINTER); g_value_init (&values.old_value, G_TYPE_POINTER);
g_value_set_pointer (&values.old_value, atk_parent); g_value_set_pointer (&values.old_value, atk_parent);
@@ -649,7 +657,7 @@ cally_actor_get_extents (AtkComponent *component,
ClutterActor *actor = NULL; ClutterActor *actor = NULL;
gint top_level_x, top_level_y; gint top_level_x, top_level_y;
gfloat f_width, f_height; gfloat f_width, f_height;
graphene_point3d_t verts[4]; ClutterVertex verts[4];
ClutterActor *stage = NULL; ClutterActor *stage = NULL;
g_return_if_fail (CALLY_IS_ACTOR (component)); g_return_if_fail (CALLY_IS_ACTOR (component));
@@ -766,7 +774,6 @@ cally_actor_action_do_action (AtkAction *action,
AtkStateSet *set = NULL; AtkStateSet *set = NULL;
CallyActorPrivate *priv = NULL; CallyActorPrivate *priv = NULL;
CallyActorActionInfo *info = NULL; CallyActorActionInfo *info = NULL;
gboolean did_action = FALSE;
cally_actor = CALLY_ACTOR (action); cally_actor = CALLY_ACTOR (action);
priv = cally_actor->priv; priv = cally_actor->priv;
@@ -774,19 +781,21 @@ cally_actor_action_do_action (AtkAction *action,
set = atk_object_ref_state_set (ATK_OBJECT (cally_actor)); set = atk_object_ref_state_set (ATK_OBJECT (cally_actor));
if (atk_state_set_contains_state (set, ATK_STATE_DEFUNCT)) if (atk_state_set_contains_state (set, ATK_STATE_DEFUNCT))
goto out; return FALSE;
if (!atk_state_set_contains_state (set, ATK_STATE_SENSITIVE) || if (!atk_state_set_contains_state (set, ATK_STATE_SENSITIVE) ||
!atk_state_set_contains_state (set, ATK_STATE_SHOWING)) !atk_state_set_contains_state (set, ATK_STATE_SHOWING))
goto out; return FALSE;
g_object_unref (set);
info = _cally_actor_get_action_info (cally_actor, index); info = _cally_actor_get_action_info (cally_actor, index);
if (info == NULL) if (info == NULL)
goto out; return FALSE;
if (info->do_action_func == NULL) if (info->do_action_func == NULL)
goto out; return FALSE;
if (!priv->action_queue) if (!priv->action_queue)
priv->action_queue = g_queue_new (); priv->action_queue = g_queue_new ();
@@ -796,12 +805,7 @@ cally_actor_action_do_action (AtkAction *action,
if (!priv->action_idle_handler) if (!priv->action_idle_handler)
priv->action_idle_handler = g_idle_add (idle_do_action, cally_actor); priv->action_idle_handler = g_idle_add (idle_do_action, cally_actor);
did_action = TRUE; return TRUE;
out:
g_clear_object (&set);
return did_action;
} }
static gboolean static gboolean
@@ -967,7 +971,7 @@ cally_actor_real_notify_clutter (GObject *obj,
* paint it; we don't want this to generate an ATK * paint it; we don't want this to generate an ATK
* state change * state change
*/ */
if (clutter_actor_is_painting_unmapped (actor)) if (clutter_actor_is_in_clone_paint (actor))
return; return;
state = ATK_STATE_SHOWING; state = ATK_STATE_SHOWING;
@@ -1032,6 +1036,8 @@ _cally_actor_get_action_info (CallyActor *cally_actor,
* Adds a new action to be accessed with the #AtkAction interface. * Adds a new action to be accessed with the #AtkAction interface.
* *
* Return value: added action id, or -1 if failure * Return value: added action id, or -1 if failure
*
* Since: 1.4
*/ */
guint guint
cally_actor_add_action (CallyActor *cally_actor, cally_actor_add_action (CallyActor *cally_actor,
@@ -1061,6 +1067,8 @@ cally_actor_add_action (CallyActor *cally_actor,
* Adds a new action to be accessed with the #AtkAction interface. * Adds a new action to be accessed with the #AtkAction interface.
* *
* Return value: added action id, or -1 if failure * Return value: added action id, or -1 if failure
*
* Since: 1.6
*/ */
guint guint
cally_actor_add_action_full (CallyActor *cally_actor, cally_actor_add_action_full (CallyActor *cally_actor,
@@ -1079,7 +1087,7 @@ cally_actor_add_action_full (CallyActor *cally_actor,
priv = cally_actor->priv; priv = cally_actor->priv;
info = g_new0 (CallyActorActionInfo, 1); info = g_slice_new (CallyActorActionInfo);
info->name = g_strdup (action_name); info->name = g_strdup (action_name);
info->description = g_strdup (action_description); info->description = g_strdup (action_description);
info->keybinding = g_strdup (action_keybinding); info->keybinding = g_strdup (action_keybinding);
@@ -1097,9 +1105,11 @@ cally_actor_add_action_full (CallyActor *cally_actor,
* @cally_actor: a #CallyActor * @cally_actor: a #CallyActor
* @action_id: the action id * @action_id: the action id
* *
* Removes a action, using the @action_id returned by [method@Actor.add_action] * Removes a action, using the @action_id returned by cally_actor_add_action()
* *
* Return value: %TRUE if the operation was successful, %FALSE otherwise * Return value: %TRUE if the operation was succesful, %FALSE otherwise
*
* Since: 1.4
*/ */
gboolean gboolean
cally_actor_remove_action (CallyActor *cally_actor, cally_actor_remove_action (CallyActor *cally_actor,
@@ -1129,9 +1139,11 @@ cally_actor_remove_action (CallyActor *cally_actor,
* @action_name: the name of the action to remove * @action_name: the name of the action to remove
* *
* Removes an action, using the @action_name used when the action was added * Removes an action, using the @action_name used when the action was added
* with [method@Actor.add_action] * with cally_actor_add_action()
* *
* Return value: %TRUE if the operation was successful, %FALSE otherwise * Return value: %TRUE if the operation was succesful, %FALSE otherwise
*
* Since: 1.4
*/ */
gboolean gboolean
cally_actor_remove_action_by_name (CallyActor *cally_actor, cally_actor_remove_action_by_name (CallyActor *cally_actor,
@@ -1180,5 +1192,5 @@ _cally_actor_destroy_action_info (gpointer action_info,
if (info->notify) if (info->notify)
info->notify (info->user_data); info->notify (info->user_data);
g_free (info); g_slice_free (CallyActorActionInfo, info);
} }

View File

@@ -51,6 +51,8 @@ typedef struct _CallyActorPrivate CallyActorPrivate;
* *
* Action function, to be used on #AtkAction implementations as a individual * Action function, to be used on #AtkAction implementations as a individual
* action * action
*
* Since: 1.4
*/ */
typedef void (* CallyActionFunc) (CallyActor *cally_actor); typedef void (* CallyActionFunc) (CallyActor *cally_actor);
@@ -60,14 +62,22 @@ typedef void (* CallyActionFunc) (CallyActor *cally_actor);
* @user_data: user data passed to the function * @user_data: user data passed to the function
* *
* Action function, to be used on #AtkAction implementations as * Action function, to be used on #AtkAction implementations as
* an individual action. * an individual action. Unlike #CallyActionFunc, this function
* uses the @user_data argument passed to cally_actor_add_action_full().
* *
* Unlike #CallyActionFunc, this function uses the @user_data * Since: 1.6
* argument passed to [method@Actor.add_action_full].
*/ */
typedef void (* CallyActionCallback) (CallyActor *cally_actor, typedef void (* CallyActionCallback) (CallyActor *cally_actor,
gpointer user_data); gpointer user_data);
/**
* CallyActor:
*
* The <structname>CallyActor</structname> structure contains only private
* data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _CallyActor struct _CallyActor
{ {
/*< private >*/ /*< private >*/
@@ -79,6 +89,8 @@ struct _CallyActor
/** /**
* CallyActorClass: * CallyActorClass:
* @notify_clutter: Signal handler for notify signal on Clutter actor * @notify_clutter: Signal handler for notify signal on Clutter actor
* @focus_clutter: Signal handler for key-focus-in and key-focus-out
* signal on Clutter actor. This virtual functions is deprecated.
* @add_actor: Signal handler for actor-added signal on * @add_actor: Signal handler for actor-added signal on
* ClutterContainer interface * ClutterContainer interface
* @remove_actor: Signal handler for actor-added signal on * @remove_actor: Signal handler for actor-added signal on
@@ -86,6 +98,8 @@ struct _CallyActor
* *
* The <structname>CallyActorClass</structname> structure contains * The <structname>CallyActorClass</structname> structure contains
* only private data * only private data
*
* Since: 1.4
*/ */
struct _CallyActorClass struct _CallyActorClass
{ {
@@ -96,6 +110,9 @@ struct _CallyActorClass
void (*notify_clutter) (GObject *object, void (*notify_clutter) (GObject *object,
GParamSpec *pspec); GParamSpec *pspec);
gboolean (*focus_clutter) (ClutterActor *actor,
gpointer data);
gint (*add_actor) (ClutterActor *container, gint (*add_actor) (ClutterActor *container,
ClutterActor *actor, ClutterActor *actor,
gpointer data); gpointer data);

View File

@@ -21,11 +21,12 @@
*/ */
/** /**
* CallyClone: * SECTION:cally-clone
* @Title: CallyClone
* @short_description: Implementation of the ATK interfaces for a #ClutterClone
* @see_also: #ClutterClone
* *
* Implementation of the ATK interfaces for a #ClutterClone * #CallyClone implements the required ATK interfaces of #ClutterClone
*
* #CallyClone implements the required ATK interfaces of [class@Clutter.Clone]
* *
* In particular it sets a proper role for the clone, as just a image, * In particular it sets a proper role for the clone, as just a image,
* as it is the sanest and simplest approach. * as it is the sanest and simplest approach.
@@ -99,9 +100,11 @@ cally_clone_init (CallyClone *clone)
* @actor: a #ClutterActor * @actor: a #ClutterActor
* *
* Creates a new #CallyClone for the given @actor. @actor must be a * Creates a new #CallyClone for the given @actor. @actor must be a
* [class@Clutter.Clone]. * #ClutterClone.
* *
* Return value: the newly created #AtkObject * Return value: the newly created #AtkObject
*
* Since: 1.4
*/ */
AtkObject* AtkObject*
cally_clone_new (ClutterActor *actor) cally_clone_new (ClutterActor *actor)

View File

@@ -41,6 +41,14 @@ typedef struct _CallyClone CallyClone;
typedef struct _CallyCloneClass CallyCloneClass; typedef struct _CallyCloneClass CallyCloneClass;
typedef struct _CallyClonePrivate CallyClonePrivate; typedef struct _CallyClonePrivate CallyClonePrivate;
/**
* CallyClone:
*
* The <structname>CallyClone</structname> structure contains only private
* data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _CallyClone struct _CallyClone
{ {
/*< private >*/ /*< private >*/
@@ -54,6 +62,8 @@ struct _CallyClone
* *
* The <structname>CallyCloneClass</structname> structure contains only * The <structname>CallyCloneClass</structname> structure contains only
* private data * private data
*
* Since: 1.4
*/ */
struct _CallyCloneClass struct _CallyCloneClass
{ {

View File

@@ -42,6 +42,8 @@
* It assumes that the accessibility object provides a * It assumes that the accessibility object provides a
* @opt_create_accessible method in order to create the accessibility * @opt_create_accessible method in order to create the accessibility
* object. It returns a @type GType object. * object. It returns a @type GType object.
*
* Since: 1.4
*/ */
#define CALLY_ACCESSIBLE_FACTORY(type, type_as_function, opt_create_accessible) \ #define CALLY_ACCESSIBLE_FACTORY(type, type_as_function, opt_create_accessible) \
\ \
@@ -104,6 +106,8 @@ type_as_function ## _factory_get_type (void) \
* *
* Sets the #AtkObjectFactory to be used in order to instantiate * Sets the #AtkObjectFactory to be used in order to instantiate
* accessibility objects for the actor which GType is @widget_type. * accessibility objects for the actor which GType is @widget_type.
*
* Since: 1.4
*/ */
#define CALLY_ACTOR_SET_FACTORY(widget_type, type_as_function) \ #define CALLY_ACTOR_SET_FACTORY(widget_type, type_as_function) \
atk_registry_set_factory_type (atk_get_default_registry (), \ atk_registry_set_factory_type (atk_get_default_registry (), \

View File

@@ -0,0 +1,147 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2008 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* Based on GailContainer from GAIL
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:cally-group
* @Title: CallyGroup
* @short_description: Implementation of the ATK interfaces for a #ClutterGroup
* @see_also: #ClutterGroup
*
* #CallyGroup implements the required ATK interfaces of #ClutterGroup
* In particular it exposes each of the Clutter actors contained in the
* group.
*/
#include "clutter-build-config.h"
#include "cally-group.h"
#include "cally-actor-private.h"
static gint cally_group_get_n_children (AtkObject *obj);
static AtkObject* cally_group_ref_child (AtkObject *obj,
gint i);
static void cally_group_real_initialize (AtkObject *obj,
gpointer data);
G_DEFINE_TYPE (CallyGroup, cally_group, CALLY_TYPE_ACTOR)
static void
cally_group_class_init (CallyGroupClass *klass)
{
/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
class->get_n_children = cally_group_get_n_children;
class->ref_child = cally_group_ref_child;
class->initialize = cally_group_real_initialize;
}
static void
cally_group_init (CallyGroup *group)
{
/* nothing to do yet */
}
/**
* cally_group_new:
* @actor: a #ClutterGroup
*
* Creates a #CallyGroup for @actor
*
* Return value: the newly created #CallyGroup
*
* Since: 1.4
*/
AtkObject *
cally_group_new (ClutterActor *actor)
{
GObject *object = NULL;
AtkObject *accessible = NULL;
g_return_val_if_fail (CLUTTER_IS_GROUP (actor), NULL);
object = g_object_new (CALLY_TYPE_GROUP, NULL);
accessible = ATK_OBJECT (object);
atk_object_initialize (accessible, actor);
return accessible;
}
static gint
cally_group_get_n_children (AtkObject *obj)
{
ClutterActor *actor = NULL;
gint count = 0;
g_return_val_if_fail (CALLY_IS_GROUP (obj), count);
actor = CALLY_GET_CLUTTER_ACTOR (obj);
if (actor == NULL) /* defunct */
return 0;
g_return_val_if_fail (CLUTTER_IS_GROUP(actor), count);
count = clutter_actor_get_n_children (actor);
return count;
}
static AtkObject*
cally_group_ref_child (AtkObject *obj,
gint i)
{
AtkObject *accessible = NULL;
ClutterActor *actor = NULL;
ClutterActor *child = NULL;
g_return_val_if_fail (CALLY_IS_GROUP (obj), NULL);
g_return_val_if_fail ((i >= 0), NULL);
actor = CALLY_GET_CLUTTER_ACTOR (obj);
g_return_val_if_fail (CLUTTER_IS_GROUP(actor), NULL);
child = clutter_actor_get_child_at_index (actor, i);
if (!child)
return NULL;
accessible = clutter_actor_get_accessible (child);
if (accessible != NULL)
g_object_ref (accessible);
return accessible;
}
static void
cally_group_real_initialize (AtkObject *obj,
gpointer data)
{
ATK_OBJECT_CLASS (cally_group_parent_class)->initialize (obj, data);
obj->role = ATK_ROLE_PANEL;
}

View File

@@ -0,0 +1,87 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2008 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* Based on GailContainer from GAIL
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CALLY_GROUP_H__
#define __CALLY_GROUP_H__
#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <cally/cally.h> can be included directly."
#endif
#include <cally/cally-actor.h>
#include <clutter/clutter.h>
G_BEGIN_DECLS
#define CALLY_TYPE_GROUP (cally_group_get_type ())
#define CALLY_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_GROUP, CallyGroup))
#define CALLY_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_GROUP, CallyGroupClass))
#define CALLY_IS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_GROUP))
#define CALLY_IS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_GROUP))
#define CALLY_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_GROUP, CallyGroupClass))
typedef struct _CallyGroup CallyGroup;
typedef struct _CallyGroupClass CallyGroupClass;
typedef struct _CallyGroupPrivate CallyGroupPrivate;
/**
* CallyGroup:
*
* The <structname>CallyGroup</structname> structure contains only
* private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _CallyGroup
{
/*< private >*/
CallyActor parent;
CallyGroupPrivate *priv;
};
/**
* CallyGroupClass:
*
* The <structname>CallyGroupClass</structname> structure contains only
* private data
*
* Since: 1.4
*/
struct _CallyGroupClass
{
/*< private >*/
CallyActorClass parent_class;
/* padding for future expansion */
gpointer _padding_dummy[8];
};
CLUTTER_EXPORT
GType cally_group_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT
AtkObject* cally_group_new (ClutterActor *actor);
G_END_DECLS
#endif /* __CALLY_GROUP_H__ */

View File

@@ -0,0 +1,98 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2009 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:cally-rectangle
* @short_description: Implementation of the ATK interfaces for a #ClutterRectangle
* @see_also: #ClutterRectangle
*
* #CallyRectangle implements the required ATK interfaces of #ClutterRectangle
*
* In particular it sets a proper role for the rectangle.
*/
#include "clutter-build-config.h"
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
#include "cally-rectangle.h"
#include "cally-actor-private.h"
#include "clutter-color.h"
#include "deprecated/clutter-rectangle.h"
/* AtkObject */
static void cally_rectangle_real_initialize (AtkObject *obj,
gpointer data);
G_DEFINE_TYPE (CallyRectangle, cally_rectangle, CALLY_TYPE_ACTOR)
static void
cally_rectangle_class_init (CallyRectangleClass *klass)
{
/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
class->initialize = cally_rectangle_real_initialize;
}
static void
cally_rectangle_init (CallyRectangle *rectangle)
{
/* nothing to do yet */
}
/**
* cally_rectangle_new:
* @actor: a #ClutterActor
*
* Creates a new #CallyRectangle for the given @actor. @actor must be
* a #ClutterRectangle.
*
* Return value: the newly created #AtkObject
*
* Since: 1.4
*/
AtkObject*
cally_rectangle_new (ClutterActor *actor)
{
GObject *object = NULL;
AtkObject *accessible = NULL;
g_return_val_if_fail (CLUTTER_IS_RECTANGLE (actor), NULL);
object = g_object_new (CALLY_TYPE_RECTANGLE, NULL);
accessible = ATK_OBJECT (object);
atk_object_initialize (accessible, actor);
return accessible;
}
static void
cally_rectangle_real_initialize (AtkObject *obj,
gpointer data)
{
ATK_OBJECT_CLASS (cally_rectangle_parent_class)->initialize (obj, data);
obj->role = ATK_ROLE_IMAGE;
}

View File

@@ -0,0 +1,84 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2009 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CALLY_RECTANGLE_H__
#define __CALLY_RECTANGLE_H__
#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <cally/cally.h> can be included directly."
#endif
#include <cally/cally-actor.h>
#include <clutter/clutter.h>
G_BEGIN_DECLS
#define CALLY_TYPE_RECTANGLE (cally_rectangle_get_type ())
#define CALLY_RECTANGLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_RECTANGLE, CallyRectangle))
#define CALLY_RECTANGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_RECTANGLE, CallyRectangleClass))
#define CALLY_IS_RECTANGLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_RECTANGLE))
#define CALLY_IS_RECTANGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_RECTANGLE))
#define CALLY_RECTANGLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_RECTANGLE, CallyRectangleClass))
typedef struct _CallyRectangle CallyRectangle;
typedef struct _CallyRectangleClass CallyRectangleClass;
typedef struct _CallyRectanglePrivate CallyRectanglePrivate;
/**
* CallyRectangle:
*
* The <structname>CallyRectangle</structname> structure contains only private
* data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _CallyRectangle
{
/*< private >*/
CallyActor parent;
CallyRectanglePrivate *priv;
};
/**
* CallyRectangleClass:
*
* The <structname>CallyRectangleClass</structname> structure contains
* only private data
*
* Since: 1.4
*/
struct _CallyRectangleClass
{
/*< private >*/
CallyActorClass parent_class;
/* padding for future expansion */
gpointer _padding_dummy[8];
};
CLUTTER_EXPORT
GType cally_rectangle_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT
AtkObject* cally_rectangle_new (ClutterActor *actor);
G_END_DECLS
#endif /* __CALLY_RECTANGLE_H__ */

View File

@@ -21,18 +21,18 @@
*/ */
/** /**
* CallyRoot: * SECTION:cally-root
* * @short_description: Root object for the Cally toolkit
* Root object for the Cally toolkit * @see_also: #ClutterStage
* *
* #CallyRoot is the root object of the accessibility tree-like * #CallyRoot is the root object of the accessibility tree-like
* hierarchy, exposing the application level. * hierarchy, exposing the application level.
* *
* Somewhat equivalent to #GailTopLevel. We consider that this class * Somewhat equivalent to #GailTopLevel. We consider that this class
* expose the a11y information of the [class@Clutter.StageManager], as the * expose the a11y information of the #ClutterStageManager, as the
* children of this object are the different [class@Clutter.Stage] managed (so * children of this object are the different ClutterStage managed (so
* the [class@GObject.Object] used in the atk_object_initialize() is the * the #GObject used in the atk_object_initialize() is the
* [class@Clutter.StageManager]). * #ClutterStageManager).
*/ */
#include "clutter-build-config.h" #include "clutter-build-config.h"
@@ -75,8 +75,8 @@ struct _CallyRootPrivate
GSList *stage_list; GSList *stage_list;
/* signals id */ /* signals id */
gulong stage_added_id; guint stage_added_id;
gulong stage_removed_id; guint stage_removed_id;
}; };
G_DEFINE_TYPE_WITH_PRIVATE (CallyRoot, cally_root, ATK_TYPE_GOBJECT_ACCESSIBLE) G_DEFINE_TYPE_WITH_PRIVATE (CallyRoot, cally_root, ATK_TYPE_GOBJECT_ACCESSIBLE)
@@ -113,6 +113,8 @@ cally_root_init (CallyRoot *root)
* Creates a new #CallyRoot object. * Creates a new #CallyRoot object.
* *
* Return value: the newly created #AtkObject * Return value: the newly created #AtkObject
*
* Since: 1.4
*/ */
AtkObject* AtkObject*
cally_root_new (void) cally_root_new (void)
@@ -147,9 +149,11 @@ cally_root_finalize (GObject *object)
stage_manager = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (root)); stage_manager = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (root));
g_clear_signal_handler (&root->priv->stage_added_id, stage_manager); g_signal_handler_disconnect (stage_manager,
root->priv->stage_added_id);
g_clear_signal_handler (&root->priv->stage_removed_id, stage_manager); g_signal_handler_disconnect (stage_manager,
root->priv->stage_added_id);
G_OBJECT_CLASS (cally_root_parent_class)->finalize (object); G_OBJECT_CLASS (cally_root_parent_class)->finalize (object);
} }

View File

@@ -41,6 +41,14 @@ typedef struct _CallyRoot CallyRoot;
typedef struct _CallyRootClass CallyRootClass; typedef struct _CallyRootClass CallyRootClass;
typedef struct _CallyRootPrivate CallyRootPrivate; typedef struct _CallyRootPrivate CallyRootPrivate;
/**
* CallyRoot:
*
* The <structname>CallyRoot</structname> structure contains only private
* data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _CallyRoot struct _CallyRoot
{ {
/*< private >*/ /*< private >*/
@@ -54,6 +62,8 @@ struct _CallyRoot
* *
* The <structname>CallyRootClass</structname> structure contains only * The <structname>CallyRootClass</structname> structure contains only
* private data * private data
*
* Since: 1.4
*/ */
struct _CallyRootClass struct _CallyRootClass
{ {

View File

@@ -21,17 +21,18 @@
*/ */
/** /**
* CallyStage: * SECTION:cally-stage
* @Title: CallyStage
* @short_description: Implementation of the ATK interfaces for a #ClutterStage
* @see_also: #ClutterStage
* *
* Implementation of the ATK interfaces for a #ClutterStage * #CallyStage implements the required ATK interfaces for #ClutterStage
*
* #CallyStage implements the required ATK interfaces for [class@Clutter.Stage]
* *
* Some implementation details: at this moment #CallyStage is used as * Some implementation details: at this moment #CallyStage is used as
* the most similar Window object in this toolkit (ie: emitting window * the most similar Window object in this toolkit (ie: emitting window
* related signals), although the real purpose of [class@Clutter.Stage] is * related signals), although the real purpose of #ClutterStage is
* being a canvas. Anyway, this is required for applications using * being a canvas. Anyway, this is required for applications using
* just clutter, or directly [class@Clutter.Stage] * just clutter, or directly #ClutterStage
*/ */
#include "clutter-build-config.h" #include "clutter-build-config.h"
@@ -46,7 +47,7 @@ static AtkStateSet* cally_stage_ref_state_set (AtkObject *obj);
/* AtkWindow */ /* AtkWindow */
static void cally_stage_window_interface_init (AtkWindowIface *iface); static void cally_stage_window_interface_init (AtkWindowIface *iface);
/* Auxiliary */ /* Auxiliar */
static void cally_stage_activate_cb (ClutterStage *stage, static void cally_stage_activate_cb (ClutterStage *stage,
gpointer data); gpointer data);
static void cally_stage_deactivate_cb (ClutterStage *stage, static void cally_stage_deactivate_cb (ClutterStage *stage,
@@ -62,7 +63,7 @@ struct _CallyStagePrivate
G_DEFINE_TYPE_WITH_CODE (CallyStage, G_DEFINE_TYPE_WITH_CODE (CallyStage,
cally_stage, cally_stage,
CALLY_TYPE_ACTOR, CALLY_TYPE_GROUP,
G_ADD_PRIVATE (CallyStage) G_ADD_PRIVATE (CallyStage)
G_IMPLEMENT_INTERFACE (ATK_TYPE_WINDOW, G_IMPLEMENT_INTERFACE (ATK_TYPE_WINDOW,
cally_stage_window_interface_init)); cally_stage_window_interface_init));
@@ -92,9 +93,11 @@ cally_stage_init (CallyStage *cally_stage)
* @actor: a #ClutterActor * @actor: a #ClutterActor
* *
* Creates a new #CallyStage for the given @actor. @actor should be a * Creates a new #CallyStage for the given @actor. @actor should be a
* [class@Clutter.Stage]. * #ClutterStage.
* *
* Return value: the newly created #AtkObject * Return value: the newly created #AtkObject
*
* Since: 1.4
*/ */
AtkObject* AtkObject*
cally_stage_new (ClutterActor *actor) cally_stage_new (ClutterActor *actor)
@@ -130,12 +133,9 @@ cally_stage_notify_key_focus_cb (ClutterStage *stage,
AtkObject *old = NULL; AtkObject *old = NULL;
if (self->priv->key_focus != NULL) if (self->priv->key_focus != NULL)
{
if (self->priv->key_focus != CLUTTER_ACTOR (stage))
{ {
g_object_remove_weak_pointer (G_OBJECT (self->priv->key_focus), g_object_remove_weak_pointer (G_OBJECT (self->priv->key_focus),
(gpointer *) &self->priv->key_focus); (gpointer *) &self->priv->key_focus);
}
old = clutter_actor_get_accessible (self->priv->key_focus); old = clutter_actor_get_accessible (self->priv->key_focus);
} }
else else
@@ -160,11 +160,8 @@ cally_stage_notify_key_focus_cb (ClutterStage *stage,
* *
* we remove the weak pointer above. * we remove the weak pointer above.
*/ */
if (key_focus != CLUTTER_ACTOR (stage))
{
g_object_add_weak_pointer (G_OBJECT (self->priv->key_focus), g_object_add_weak_pointer (G_OBJECT (self->priv->key_focus),
(gpointer *) &self->priv->key_focus); (gpointer *) &self->priv->key_focus);
}
new = clutter_actor_get_accessible (key_focus); new = clutter_actor_get_accessible (key_focus);
} }
@@ -225,7 +222,7 @@ cally_stage_window_interface_init (AtkWindowIface *iface)
/* At this moment AtkWindow is just about signals */ /* At this moment AtkWindow is just about signals */
} }
/* Auxiliary */ /* Auxiliar */
static void static void
cally_stage_activate_cb (ClutterStage *stage, cally_stage_activate_cb (ClutterStage *stage,
gpointer data) gpointer data)

View File

@@ -25,7 +25,7 @@
#error "Only <cally/cally.h> can be included directly." #error "Only <cally/cally.h> can be included directly."
#endif #endif
#include <cally/cally-actor.h> #include <cally/cally-group.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@@ -41,10 +41,18 @@ typedef struct _CallyStage CallyStage;
typedef struct _CallyStageClass CallyStageClass; typedef struct _CallyStageClass CallyStageClass;
typedef struct _CallyStagePrivate CallyStagePrivate; typedef struct _CallyStagePrivate CallyStagePrivate;
/**
* CallyStage:
*
* The <structname>CallyStage</structname> structure contains only
* private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _CallyStage struct _CallyStage
{ {
/*< private >*/ /*< private >*/
CallyActor parent; CallyGroup parent;
CallyStagePrivate *priv; CallyStagePrivate *priv;
}; };
@@ -54,11 +62,13 @@ struct _CallyStage
* *
* The <structname>CallyStageClass</structname> structure contains only * The <structname>CallyStageClass</structname> structure contains only
* private data * private data
*
* Since: 1.4
*/ */
struct _CallyStageClass struct _CallyStageClass
{ {
/*< private >*/ /*< private >*/
CallyActorClass parent_class; CallyGroupClass parent_class;
/* padding for future expansion */ /* padding for future expansion */
gpointer _padding_dummy[16]; gpointer _padding_dummy[16];

View File

@@ -29,12 +29,14 @@
*/ */
/** /**
* CallyText: * SECTION:cally-text
* * @short_description: Implementation of the ATK interfaces for a #ClutterText
* Implementation of the ATK interfaces for a [class@Clutter.Text] * @see_also: #ClutterText
* *
* #CallyText implements the required ATK interfaces of * #CallyText implements the required ATK interfaces of
* [class@Clutter.Text], #AtkText and #AtkEditableText * #ClutterText, #AtkText and #AtkEditableText
*
*
*/ */
#include "clutter-build-config.h" #include "clutter-build-config.h"
@@ -245,7 +247,11 @@ cally_text_finalize (GObject *obj)
/* g_object_unref (cally_text->priv->textutil); */ /* g_object_unref (cally_text->priv->textutil); */
/* cally_text->priv->textutil = NULL; */ /* cally_text->priv->textutil = NULL; */
g_clear_handle_id (&cally_text->priv->insert_idle_handler, g_source_remove); if (cally_text->priv->insert_idle_handler)
{
g_source_remove (cally_text->priv->insert_idle_handler);
cally_text->priv->insert_idle_handler = 0;
}
G_OBJECT_CLASS (cally_text_parent_class)->finalize (obj); G_OBJECT_CLASS (cally_text_parent_class)->finalize (obj);
} }
@@ -255,9 +261,11 @@ cally_text_finalize (GObject *obj)
* @actor: a #ClutterActor * @actor: a #ClutterActor
* *
* Creates a new #CallyText for the given @actor. @actor must be a * Creates a new #CallyText for the given @actor. @actor must be a
* [class@Clutter.Text]. * #ClutterText.
* *
* Return value: the newly created #AtkObject * Return value: the newly created #AtkObject
*
* Since: 1.4
*/ */
AtkObject* AtkObject*
cally_text_new (ClutterActor *actor) cally_text_new (ClutterActor *actor)
@@ -1430,7 +1438,7 @@ static void cally_text_get_character_extents (AtkText *text,
PangoLayout *layout; PangoLayout *layout;
PangoRectangle extents; PangoRectangle extents;
const gchar *text_value; const gchar *text_value;
graphene_point3d_t verts[4]; ClutterVertex verts[4];
actor = CALLY_GET_CLUTTER_ACTOR (text); actor = CALLY_GET_CLUTTER_ACTOR (text);
if (actor == NULL) /* State is defunct */ if (actor == NULL) /* State is defunct */
@@ -1509,7 +1517,7 @@ cally_text_get_offset_at_point (AtkText *text,
} }
/******** Auxiliary private methods ******/ /******** Auxiliar private methods ******/
/* ClutterText only maintains the current cursor position and a extra selection /* ClutterText only maintains the current cursor position and a extra selection
bound, but this could be before or after the cursor. This method returns bound, but this could be before or after the cursor. This method returns
@@ -1548,7 +1556,7 @@ _cally_text_delete_text_cb (ClutterText *clutter_text,
g_return_if_fail (CALLY_IS_TEXT (data)); g_return_if_fail (CALLY_IS_TEXT (data));
/* Ignore zero length deletions */ /* Ignore zero lengh deletions */
if (end_pos - start_pos == 0) if (end_pos - start_pos == 0)
return; return;
@@ -1649,7 +1657,7 @@ cally_text_insert_text (AtkEditableText *text,
clutter_text_insert_text (CLUTTER_TEXT (actor), clutter_text_insert_text (CLUTTER_TEXT (actor),
string, *position); string, *position);
/* we suppose that the text insertion will be successful, /* we suppose that the text insertion will be succesful,
clutter-text doesn't warn about it. A option would be search for clutter-text doesn't warn about it. A option would be search for
the text, but it seems not really required */ the text, but it seems not really required */
*position += length; *position += length;
@@ -1862,7 +1870,7 @@ static gint
_cally_atk_attribute_lookup_func (gconstpointer data, _cally_atk_attribute_lookup_func (gconstpointer data,
gconstpointer user_data) gconstpointer user_data)
{ {
AtkTextAttribute attr = (AtkTextAttribute) GPOINTER_TO_INT (user_data); AtkTextAttribute attr = (AtkTextAttribute) user_data;
AtkAttribute *at = (AtkAttribute *) data; AtkAttribute *at = (AtkAttribute *) data;
if (!g_strcmp0 (at->name, atk_text_attribute_get_name (attr))) if (!g_strcmp0 (at->name, atk_text_attribute_get_name (attr)))
return 0; return 0;
@@ -2286,7 +2294,7 @@ _cally_misc_get_index_at_point (ClutterText *clutter_text,
gint index, x_window, y_window, x_toplevel, y_toplevel; gint index, x_window, y_window, x_toplevel, y_toplevel;
gint x_temp, y_temp; gint x_temp, y_temp;
gboolean ret; gboolean ret;
graphene_point3d_t verts[4]; ClutterVertex verts[4];
PangoLayout *layout; PangoLayout *layout;
gint x_layout, y_layout; gint x_layout, y_layout;

View File

@@ -41,6 +41,14 @@ typedef struct _CallyText CallyText;
typedef struct _CallyTextClass CallyTextClass; typedef struct _CallyTextClass CallyTextClass;
typedef struct _CallyTextPrivate CallyTextPrivate; typedef struct _CallyTextPrivate CallyTextPrivate;
/**
* CallyText:
*
* The <structname>CallyText</structname> structure contains only private
* data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _CallyText struct _CallyText
{ {
/*< private >*/ /*< private >*/
@@ -54,6 +62,8 @@ struct _CallyText
* *
* The <structname>CallyTextClass</structname> structure contains only * The <structname>CallyTextClass</structname> structure contains only
* private data * private data
*
* Since: 1.4
*/ */
struct _CallyTextClass struct _CallyTextClass
{ {

View File

@@ -0,0 +1,98 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2009 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:cally-texture
* @Title: CallyTexture
* @short_description: Implementation of the ATK interfaces for a #ClutterTexture
* @see_also: #ClutterTexture
*
* #CallyTexture implements the required ATK interfaces of #ClutterTexture
*
* In particular it sets a proper role for the texture.
*/
#include "clutter-build-config.h"
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
#include "cally-texture.h"
#include "cally-actor-private.h"
#include "deprecated/clutter-texture.h"
/* AtkObject */
static void cally_texture_real_initialize (AtkObject *obj,
gpointer data);
G_DEFINE_TYPE (CallyTexture, cally_texture, CALLY_TYPE_ACTOR)
static void
cally_texture_class_init (CallyTextureClass *klass)
{
/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
class->initialize = cally_texture_real_initialize;
}
static void
cally_texture_init (CallyTexture *texture)
{
/* nothing to do yet */
}
/**
* cally_texture_new:
* @actor: a #ClutterActor
*
* Creates a new #CallyTexture for the given @actor. @actor must be
* a #ClutterTexture.
*
* Return value: the newly created #AtkObject
*
* Since: 1.4
*/
AtkObject*
cally_texture_new (ClutterActor *actor)
{
GObject *object = NULL;
AtkObject *accessible = NULL;
g_return_val_if_fail (CLUTTER_IS_TEXTURE (actor), NULL);
object = g_object_new (CALLY_TYPE_TEXTURE, NULL);
accessible = ATK_OBJECT (object);
atk_object_initialize (accessible, actor);
return accessible;
}
static void
cally_texture_real_initialize (AtkObject *obj,
gpointer data)
{
ATK_OBJECT_CLASS (cally_texture_parent_class)->initialize (obj, data);
/* default role */
obj->role = ATK_ROLE_IMAGE;
}

View File

@@ -0,0 +1,84 @@
/* CALLY - The Clutter Accessibility Implementation Library
*
* Copyright (C) 2009 Igalia, S.L.
*
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CALLY_TEXTURE_H__
#define __CALLY_TEXTURE_H__
#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <cally/cally.h> can be included directly."
#endif
#include <clutter/clutter.h>
#include <cally/cally-actor.h>
G_BEGIN_DECLS
#define CALLY_TYPE_TEXTURE (cally_texture_get_type ())
#define CALLY_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_TEXTURE, CallyTexture))
#define CALLY_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_TEXTURE, CallyTextureClass))
#define CALLY_IS_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_TEXTURE))
#define CALLY_IS_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_TEXTURE))
#define CALLY_TEXTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_TEXTURE, CallyTextureClass))
typedef struct _CallyTexture CallyTexture;
typedef struct _CallyTextureClass CallyTextureClass;
typedef struct _CallyTexturePrivate CallyTexturePrivate;
/**
* CallyTexture:
*
* The <structname>CallyTexture</structname> structure contains only
* private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _CallyTexture
{
/*< private >*/
CallyActor parent;
CallyTexturePrivate *priv;
};
/**
* CallyTextureClass:
*
* The <structname>CallyTextureClass</structname> structure contains
* only private data
*
* Since: 1.4
*/
struct _CallyTextureClass
{
/*< private >*/
CallyActorClass parent_class;
/* padding for future expansion */
gpointer _padding_dummy[8];
};
CLUTTER_EXPORT
GType cally_texture_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT
AtkObject *cally_texture_new (ClutterActor *actor);
G_END_DECLS
#endif /* __CALLY_TEXTURE_H__ */

View File

@@ -24,9 +24,10 @@
*/ */
/** /**
* CallyUtil: * SECTION:cally-util
* * @Title: CallyUtil
* #AtkUtil implementation * @short_description: #AtkUtil implementation
* @see_also: #ClutterActor
* *
* #CallyUtil implements #AtkUtil abstract methods. Although it * #CallyUtil implements #AtkUtil abstract methods. Although it
* includes the name "Util" it is in fact one of the most important * includes the name "Util" it is in fact one of the most important
@@ -59,6 +60,17 @@ static const gchar * cally_util_get_toolkit_name (void);
static const gchar * cally_util_get_toolkit_version (void); static const gchar * cally_util_get_toolkit_version (void);
/* private */ /* private */
static void cally_util_simulate_snooper_install (void);
static void cally_util_simulate_snooper_remove (void);
static gboolean cally_key_snooper (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data);
static void cally_util_stage_added_cb (ClutterStageManager *stage_manager,
ClutterStage *stage,
gpointer data);
static void cally_util_stage_removed_cb (ClutterStageManager *stage_manager,
ClutterStage *stage,
gpointer data);
static gboolean notify_hf (gpointer key, static gboolean notify_hf (gpointer key,
gpointer value, gpointer value,
gpointer data); gpointer data);
@@ -141,8 +153,12 @@ cally_util_add_key_event_listener (AtkKeySnoopFunc listener,
CallyKeyEventInfo *event_info = NULL; CallyKeyEventInfo *event_info = NULL;
if (!key_listener_list) if (!key_listener_list)
{
key_listener_list = g_hash_table_new_full (NULL, NULL, NULL, g_free); key_listener_list = g_hash_table_new_full (NULL, NULL, NULL, g_free);
cally_util_simulate_snooper_install ();
}
event_info = g_new (CallyKeyEventInfo, 1); event_info = g_new (CallyKeyEventInfo, 1);
event_info->listener = listener; event_info->listener = listener;
event_info->func_data = data; event_info->func_data = data;
@@ -163,11 +179,75 @@ cally_util_remove_key_event_listener (guint remove_listener)
{ {
g_hash_table_destroy (key_listener_list); g_hash_table_destroy (key_listener_list);
key_listener_list = NULL; key_listener_list = NULL;
cally_util_simulate_snooper_remove ();
} }
} }
/* ------------------------------ PRIVATE FUNCTIONS ------------------------- */ /* ------------------------------ PRIVATE FUNCTIONS ------------------------- */
/* Trying to emulate gtk_key_snooper install (a kind of wrapper). This
could be implemented without it, but I will maintain it in this
way, so if in the future clutter implements it natively it would be
easier the transition */
static void
cally_util_simulate_snooper_install (void)
{
ClutterStageManager *stage_manager = NULL;
ClutterStage *stage = NULL;
GSList *stage_list = NULL;
GSList *iter = NULL;
stage_manager = clutter_stage_manager_get_default ();
stage_list = clutter_stage_manager_list_stages (stage_manager);
for (iter = stage_list; iter != NULL; iter = g_slist_next (iter))
{
stage = CLUTTER_STAGE (iter->data);
g_signal_connect (G_OBJECT (stage), "captured-event",
G_CALLBACK (cally_key_snooper), NULL);
}
g_signal_connect (G_OBJECT (stage_manager), "stage-added",
G_CALLBACK (cally_util_stage_added_cb), cally_key_snooper);
g_signal_connect (G_OBJECT (stage_manager), "stage-removed",
G_CALLBACK (cally_util_stage_removed_cb), cally_key_snooper);
g_slist_free (stage_list);
}
static void
cally_util_simulate_snooper_remove (void)
{
ClutterStageManager *stage_manager = NULL;
ClutterStage *stage = NULL;
GSList *stage_list = NULL;
GSList *iter = NULL;
gint num = 0;
stage_manager = clutter_stage_manager_get_default ();
stage_list = clutter_stage_manager_list_stages (stage_manager);
for (iter = stage_list; iter != NULL; iter = g_slist_next (iter))
{
stage = CLUTTER_STAGE (iter->data);
num += g_signal_handlers_disconnect_by_func (stage, cally_key_snooper, NULL);
}
g_signal_handlers_disconnect_by_func (G_OBJECT (stage_manager),
G_CALLBACK (cally_util_stage_added_cb),
cally_key_snooper);
g_signal_handlers_disconnect_by_func (G_OBJECT (stage_manager),
G_CALLBACK (cally_util_stage_removed_cb),
cally_key_snooper);
#ifdef CALLY_DEBUG
g_print ("Number of snooper callbacks disconnected: %i\n", num);
#endif
}
static AtkKeyEventStruct * static AtkKeyEventStruct *
atk_key_event_from_clutter_event_key (ClutterKeyEvent *clutter_event, atk_key_event_from_clutter_event_key (ClutterKeyEvent *clutter_event,
gunichar password_char) gunichar password_char)
@@ -281,11 +361,8 @@ insert_hf (gpointer key, gpointer value, gpointer data)
static gunichar static gunichar
check_key_visibility (ClutterEvent *event) check_key_visibility (ClutterEvent *event)
{ {
AtkObject *accessible; ClutterKeyEvent *key_event = (ClutterKeyEvent *)event;
ClutterActor *focus; AtkObject *accessible = clutter_actor_get_accessible (key_event->source);
focus = clutter_stage_get_key_focus (clutter_event_get_stage (event));
accessible = clutter_actor_get_accessible (focus);
g_return_val_if_fail (accessible != NULL, 0); g_return_val_if_fail (accessible != NULL, 0);
@@ -301,40 +378,65 @@ check_key_visibility (ClutterEvent *event)
still better fill this with a default unichar that the original still better fill this with a default unichar that the original
one */ one */
if (CLUTTER_IS_TEXT (focus)) if (CLUTTER_IS_TEXT (key_event->source))
return clutter_text_get_password_char (CLUTTER_TEXT (focus)); return clutter_text_get_password_char (CLUTTER_TEXT (key_event->source));
else else
return DEFAULT_PASSWORD_CHAR; return DEFAULT_PASSWORD_CHAR;
} }
gboolean static gboolean
cally_snoop_key_event (ClutterKeyEvent *key) cally_key_snooper (ClutterActor *actor,
ClutterEvent *event,
gpointer user_data)
{ {
ClutterEvent *event = (ClutterEvent *) key;
AtkKeyEventStruct *key_event = NULL; AtkKeyEventStruct *key_event = NULL;
gboolean consumed = FALSE; gint consumed = 0;
gunichar password_char = 0; gunichar password_char = 0;
/* filter key events */ /* filter key events */
if ((event->type != CLUTTER_KEY_PRESS) && (event->type != CLUTTER_KEY_RELEASE)) if ((event->type != CLUTTER_KEY_PRESS) && (event->type != CLUTTER_KEY_RELEASE))
{
return FALSE; return FALSE;
}
password_char = check_key_visibility (event);
if (key_listener_list) if (key_listener_list)
{ {
GHashTable *new_hash = g_hash_table_new (NULL, NULL); GHashTable *new_hash = g_hash_table_new (NULL, NULL);
g_hash_table_foreach (key_listener_list, insert_hf, new_hash); g_hash_table_foreach (key_listener_list, insert_hf, new_hash);
password_char = check_key_visibility (event); key_event = atk_key_event_from_clutter_event_key ((ClutterKeyEvent *)event,
key_event = atk_key_event_from_clutter_event_key (key, password_char); password_char);
/* func data is inside the hash table */ /* func data is inside the hash table */
consumed = g_hash_table_foreach_steal (new_hash, notify_hf, key_event) > 0; consumed = g_hash_table_foreach_steal (new_hash, notify_hf, key_event);
g_hash_table_destroy (new_hash); g_hash_table_destroy (new_hash);
g_free (key_event->string); g_free (key_event->string);
g_free (key_event); g_free (key_event);
} }
return consumed; return (consumed ? 1 : 0);
}
static void
cally_util_stage_added_cb (ClutterStageManager *stage_manager,
ClutterStage *stage,
gpointer data)
{
GCallback cally_key_snooper_cb = G_CALLBACK (data);
g_signal_connect (G_OBJECT (stage), "captured-event", cally_key_snooper_cb, NULL);
}
static void
cally_util_stage_removed_cb (ClutterStageManager *stage_manager,
ClutterStage *stage,
gpointer data)
{
GCallback cally_key_snooper_cb = G_CALLBACK (data);
g_signal_handlers_disconnect_by_func (stage, cally_key_snooper_cb, NULL);
} }
void void

View File

@@ -41,6 +41,14 @@ typedef struct _CallyUtil CallyUtil;
typedef struct _CallyUtilClass CallyUtilClass; typedef struct _CallyUtilClass CallyUtilClass;
typedef struct _CallyUtilPrivate CallyUtilPrivate; typedef struct _CallyUtilPrivate CallyUtilPrivate;
/**
* CallyUtil:
*
* The <structname>CallyUtil</structname> structure contains only
* private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _CallyUtil struct _CallyUtil
{ {
/*< private >*/ /*< private >*/
@@ -54,6 +62,8 @@ struct _CallyUtil
* *
* The <structname>CallyUtilClass</structname> structure contains only * The <structname>CallyUtilClass</structname> structure contains only
* private data * private data
*
* Since: 1.4
*/ */
struct _CallyUtilClass struct _CallyUtilClass
{ {
@@ -69,8 +79,6 @@ GType cally_util_get_type (void) G_GNUC_CONST;
void _cally_util_override_atk_util (void); void _cally_util_override_atk_util (void);
gboolean cally_snoop_key_event (ClutterKeyEvent *key);
G_END_DECLS G_END_DECLS
#endif /* __CALLY_UTIL_H__ */ #endif /* __CALLY_UTIL_H__ */

View File

@@ -36,8 +36,11 @@
#include "cally.h" #include "cally.h"
#include "cally-actor.h" #include "cally-actor.h"
#include "cally-group.h"
#include "cally-stage.h" #include "cally-stage.h"
#include "cally-text.h" #include "cally-text.h"
#include "cally-texture.h"
#include "cally-rectangle.h"
#include "cally-clone.h" #include "cally-clone.h"
#include "cally-factory.h" #include "cally-factory.h"
@@ -50,8 +53,11 @@
/* factories initialization*/ /* factories initialization*/
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_ACTOR, cally_actor, cally_actor_new) CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_ACTOR, cally_actor, cally_actor_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_GROUP, cally_group, cally_group_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_STAGE, cally_stage, cally_stage_new) CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_STAGE, cally_stage, cally_stage_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_TEXT, cally_text, cally_text_new) CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_TEXT, cally_text, cally_text_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_TEXTURE, cally_texture, cally_texture_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_RECTANGLE, cally_rectangle, cally_rectangle_new)
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_CLONE, cally_clone, cally_clone_new) CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_CLONE, cally_clone, cally_clone_new)
/** /**
@@ -61,14 +67,19 @@ CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_CLONE, cally_clone, cally_clone_new)
* *
* Return value: %TRUE if accessibility support has been correctly * Return value: %TRUE if accessibility support has been correctly
* initialized. * initialized.
*
* Since: 1.4
*/ */
gboolean gboolean
cally_accessibility_init (void) cally_accessibility_init (void)
{ {
/* setting the factories */ /* setting the factories */
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_ACTOR, cally_actor); CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_ACTOR, cally_actor);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_GROUP, cally_group);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_STAGE, cally_stage); CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_STAGE, cally_stage);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXT, cally_text); CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXT, cally_text);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXTURE, cally_texture);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_RECTANGLE, cally_rectangle);
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_CLONE, cally_clone); CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_CLONE, cally_clone);
/* Initialize the CallyUtility class */ /* Initialize the CallyUtility class */
@@ -86,6 +97,8 @@ cally_accessibility_init (void)
* *
* Return value: %TRUE if accessibility support has been correctly * Return value: %TRUE if accessibility support has been correctly
* initialized. * initialized.
*
* Since: 1.4
*/ */
gboolean cally_get_cally_initialized (void) gboolean cally_get_cally_initialized (void)
{ {

View File

@@ -26,10 +26,13 @@
#include "cally-actor.h" #include "cally-actor.h"
#include "cally-clone.h" #include "cally-clone.h"
#include "cally-factory.h" #include "cally-factory.h"
#include "cally-group.h"
#include "cally-main.h" #include "cally-main.h"
#include "cally-rectangle.h"
#include "cally-root.h" #include "cally-root.h"
#include "cally-stage.h" #include "cally-stage.h"
#include "cally-text.h" #include "cally-text.h"
#include "cally-texture.h"
#include "cally-util.h" #include "cally-util.h"
#undef __CALLY_H_INSIDE__ #undef __CALLY_H_INSIDE__

View File

@@ -23,81 +23,39 @@
*/ */
/** /**
* ClutterAction: * SECTION:clutter-action
* * @Title: ClutterAction
* Abstract class for event-related logic * @Short_Description: Abstract class for event-related logic
* @See_Also: #ClutterConstraint
* *
* #ClutterAction is an abstract base class for event-related actions that * #ClutterAction is an abstract base class for event-related actions that
* modify the user interaction of a [class@Actor], just like * modify the user interaction of a #ClutterActor, just like
* [class@Constraint] is an abstract class for modifiers of an actor's * #ClutterConstraint is an abstract class for modifiers of an actor's
* position or size. * position or size.
* *
* Implementations of #ClutterAction are associated to an actor and can * Implementations of #ClutterAction are associated to an actor and can
* provide behavioral changes when dealing with user input - for instance * provide behavioral changes when dealing with user input - for instance
* drag and drop capabilities, or scrolling, or panning - by using the * drag and drop capabilities, or scrolling, or panning - by using the
* various event-related signals provided by [class@Actor] itself. * various event-related signals provided by #ClutterActor itself.
*
* #ClutterAction is available since Clutter 1.4
*/ */
#include "clutter-build-config.h" #include "clutter-build-config.h"
#include "clutter-action.h" #include "clutter-action.h"
#include "clutter-action-private.h"
#include "clutter-debug.h" #include "clutter-debug.h"
#include "clutter-private.h" #include "clutter-private.h"
typedef struct _ClutterActionPrivate ClutterActionPrivate; G_DEFINE_ABSTRACT_TYPE (ClutterAction, clutter_action, CLUTTER_TYPE_ACTOR_META);
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 static void
clutter_action_class_init (ClutterActionClass *klass) clutter_action_class_init (ClutterActionClass *klass)
{ {
klass->handle_event = clutter_action_handle_event_default;
} }
static void static void
clutter_action_init (ClutterAction *self) clutter_action_init (ClutterAction *self)
{ {
} }
void
clutter_action_set_phase (ClutterAction *action,
ClutterEventPhase phase)
{
ClutterActionPrivate *priv;
priv = clutter_action_get_instance_private (action);
priv->phase = phase;
}
ClutterEventPhase
clutter_action_get_phase (ClutterAction *action)
{
ClutterActionPrivate *priv;
g_return_val_if_fail (CLUTTER_IS_ACTION (action), CLUTTER_PHASE_CAPTURE);
priv = clutter_action_get_instance_private (action);
return priv->phase;
}
gboolean
clutter_action_handle_event (ClutterAction *action,
const ClutterEvent *event)
{
return CLUTTER_ACTION_GET_CLASS (action)->handle_event (action, event);
}

View File

@@ -34,24 +34,40 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define CLUTTER_TYPE_ACTION (clutter_action_get_type ()) #define CLUTTER_TYPE_ACTION (clutter_action_get_type ())
#define CLUTTER_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTION, ClutterAction))
#define CLUTTER_IS_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTION))
#define CLUTTER_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTION, ClutterActionClass))
#define CLUTTER_IS_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTION))
#define CLUTTER_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTION, ClutterActionClass))
CLUTTER_EXPORT typedef struct _ClutterActionClass ClutterActionClass;
G_DECLARE_DERIVABLE_TYPE (ClutterAction, clutter_action,
CLUTTER, ACTION, ClutterActorMeta); /**
* ClutterAction:
*
* The #ClutterAction structure contains only private data and
* should be accessed using the provided API.
*
* Since: 1.4
*/
struct _ClutterAction
{
/*< private >*/
ClutterActorMeta parent_instance;
};
/** /**
* ClutterActionClass: * ClutterActionClass:
* *
* The ClutterActionClass structure contains only private data * The ClutterActionClass structure contains only private data
*
* Since: 1.4
*/ */
struct _ClutterActionClass struct _ClutterActionClass
{ {
/*< private >*/ /*< private >*/
ClutterActorMetaClass parent_class; ClutterActorMetaClass parent_class;
gboolean (* handle_event) (ClutterAction *action,
const ClutterEvent *event);
void (* _clutter_action1) (void); void (* _clutter_action1) (void);
void (* _clutter_action2) (void); void (* _clutter_action2) (void);
void (* _clutter_action3) (void); void (* _clutter_action3) (void);
@@ -62,6 +78,9 @@ struct _ClutterActionClass
void (* _clutter_action8) (void); void (* _clutter_action8) (void);
}; };
CLUTTER_EXPORT
GType clutter_action_get_type (void) G_GNUC_CONST;
/* ClutterActor API */ /* ClutterActor API */
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_add_action (ClutterActor *self, void clutter_actor_add_action (ClutterActor *self,
@@ -71,11 +90,6 @@ void clutter_actor_add_action_with_name (ClutterActor *self,
const gchar *name, const gchar *name,
ClutterAction *action); ClutterAction *action);
CLUTTER_EXPORT 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, void clutter_actor_remove_action (ClutterActor *self,
ClutterAction *action); ClutterAction *action);
CLUTTER_EXPORT CLUTTER_EXPORT
@@ -92,8 +106,6 @@ void clutter_actor_clear_actions (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_EXPORT
gboolean clutter_actor_has_actions (ClutterActor *self); gboolean clutter_actor_has_actions (ClutterActor *self);
ClutterEventPhase clutter_action_get_phase (ClutterAction *action);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_ACTION_H__ */ #endif /* __CLUTTER_ACTION_H__ */

View File

@@ -14,19 +14,21 @@
* @x_2: X coordinate of the bottom right point * @x_2: X coordinate of the bottom right point
* @y_2: Y coordinate of the bottom right point * @y_2: Y coordinate of the bottom right point
* *
* Allocates a new [struct@ActorBox] using the passed coordinates * Allocates a new #ClutterActorBox using the passed coordinates
* for the top left and bottom right points. * for the top left and bottom right points.
* *
* This function is the logical equivalent of: * This function is the logical equivalent of:
* *
* ```c * |[
* clutter_actor_box_init (clutter_actor_box_alloc (), * clutter_actor_box_init (clutter_actor_box_alloc (),
* x_1, y_1, * x_1, y_1,
* x_2, y_2); * x_2, y_2);
* ``` * ]|
* *
* Return value: (transfer full): the newly allocated #ClutterActorBox. * Return value: (transfer full): the newly allocated #ClutterActorBox.
* Use [method@ActorBox.free] to free the resources * Use clutter_actor_box_free() to free the resources
*
* Since: 1.0
*/ */
ClutterActorBox * ClutterActorBox *
clutter_actor_box_new (gfloat x_1, clutter_actor_box_new (gfloat x_1,
@@ -42,15 +44,17 @@ clutter_actor_box_new (gfloat x_1,
/** /**
* clutter_actor_box_alloc: * clutter_actor_box_alloc:
* *
* Allocates a new [struct@ActorBox]. * Allocates a new #ClutterActorBox.
* *
* Return value: (transfer full): the newly allocated #ClutterActorBox. * Return value: (transfer full): the newly allocated #ClutterActorBox.
* Use [method@ActorBox.free] to free its resources * Use clutter_actor_box_free() to free its resources
*
* Since: 1.12
*/ */
ClutterActorBox * ClutterActorBox *
clutter_actor_box_alloc (void) clutter_actor_box_alloc (void)
{ {
return g_new0 (ClutterActorBox, 1); return g_slice_new0 (ClutterActorBox);
} }
/** /**
@@ -64,6 +68,8 @@ clutter_actor_box_alloc (void)
* Initializes @box with the given coordinates. * Initializes @box with the given coordinates.
* *
* Return value: (transfer none): the initialized #ClutterActorBox * Return value: (transfer none): the initialized #ClutterActorBox
*
* Since: 1.10
*/ */
ClutterActorBox * ClutterActorBox *
clutter_actor_box_init (ClutterActorBox *box, clutter_actor_box_init (ClutterActorBox *box,
@@ -91,6 +97,8 @@ clutter_actor_box_init (ClutterActorBox *box,
* @height: height of the box * @height: height of the box
* *
* Initializes @box with the given origin and size. * Initializes @box with the given origin and size.
*
* Since: 1.10
*/ */
void void
clutter_actor_box_init_rect (ClutterActorBox *box, clutter_actor_box_init_rect (ClutterActorBox *box,
@@ -114,13 +122,15 @@ clutter_actor_box_init_rect (ClutterActorBox *box,
* Copies @box * Copies @box
* *
* Return value: a newly allocated copy of #ClutterActorBox. Use * Return value: a newly allocated copy of #ClutterActorBox. Use
* [method@ActorBox.free] to free the allocated resources * clutter_actor_box_free() to free the allocated resources
*
* Since: 1.0
*/ */
ClutterActorBox * ClutterActorBox *
clutter_actor_box_copy (const ClutterActorBox *box) clutter_actor_box_copy (const ClutterActorBox *box)
{ {
if (G_LIKELY (box != NULL)) if (G_LIKELY (box != NULL))
return g_memdup2 (box, sizeof (ClutterActorBox)); return g_slice_dup (ClutterActorBox, box);
return NULL; return NULL;
} }
@@ -129,14 +139,16 @@ clutter_actor_box_copy (const ClutterActorBox *box)
* clutter_actor_box_free: * clutter_actor_box_free:
* @box: a #ClutterActorBox * @box: a #ClutterActorBox
* *
* Frees a #ClutterActorBox allocated using [ctor@ActorBox.new] * Frees a #ClutterActorBox allocated using clutter_actor_box_new()
* or [method@ActorBox.copy]. * or clutter_actor_box_copy()
*
* Since: 1.0
*/ */
void void
clutter_actor_box_free (ClutterActorBox *box) clutter_actor_box_free (ClutterActorBox *box)
{ {
if (G_LIKELY (box != NULL)) if (G_LIKELY (box != NULL))
g_free (box); g_slice_free (ClutterActorBox, box);
} }
/** /**
@@ -147,6 +159,8 @@ clutter_actor_box_free (ClutterActorBox *box)
* Checks @box_a and @box_b for equality * Checks @box_a and @box_b for equality
* *
* Return value: %TRUE if the passed #ClutterActorBox are equal * Return value: %TRUE if the passed #ClutterActorBox are equal
*
* Since: 1.0
*/ */
gboolean gboolean
clutter_actor_box_equal (const ClutterActorBox *box_a, clutter_actor_box_equal (const ClutterActorBox *box_a,
@@ -168,6 +182,8 @@ clutter_actor_box_equal (const ClutterActorBox *box_a,
* Retrieves the X coordinate of the origin of @box * Retrieves the X coordinate of the origin of @box
* *
* Return value: the X coordinate of the origin * Return value: the X coordinate of the origin
*
* Since: 1.0
*/ */
gfloat gfloat
clutter_actor_box_get_x (const ClutterActorBox *box) clutter_actor_box_get_x (const ClutterActorBox *box)
@@ -184,6 +200,8 @@ clutter_actor_box_get_x (const ClutterActorBox *box)
* Retrieves the Y coordinate of the origin of @box * Retrieves the Y coordinate of the origin of @box
* *
* Return value: the Y coordinate of the origin * Return value: the Y coordinate of the origin
*
* Since: 1.0
*/ */
gfloat gfloat
clutter_actor_box_get_y (const ClutterActorBox *box) clutter_actor_box_get_y (const ClutterActorBox *box)
@@ -200,6 +218,8 @@ clutter_actor_box_get_y (const ClutterActorBox *box)
* Retrieves the width of the @box * Retrieves the width of the @box
* *
* Return value: the width of the box * Return value: the width of the box
*
* Since: 1.0
*/ */
gfloat gfloat
clutter_actor_box_get_width (const ClutterActorBox *box) clutter_actor_box_get_width (const ClutterActorBox *box)
@@ -216,6 +236,8 @@ clutter_actor_box_get_width (const ClutterActorBox *box)
* Retrieves the height of the @box * Retrieves the height of the @box
* *
* Return value: the height of the box * Return value: the height of the box
*
* Since: 1.0
*/ */
gfloat gfloat
clutter_actor_box_get_height (const ClutterActorBox *box) clutter_actor_box_get_height (const ClutterActorBox *box)
@@ -232,6 +254,8 @@ clutter_actor_box_get_height (const ClutterActorBox *box)
* @y: (out) (allow-none): return location for the Y coordinate, or %NULL * @y: (out) (allow-none): return location for the Y coordinate, or %NULL
* *
* Retrieves the origin of @box * Retrieves the origin of @box
*
* Since: 1.0
*/ */
void void
clutter_actor_box_get_origin (const ClutterActorBox *box, clutter_actor_box_get_origin (const ClutterActorBox *box,
@@ -254,6 +278,8 @@ clutter_actor_box_get_origin (const ClutterActorBox *box,
* @height: (out) (allow-none): return location for the height, or %NULL * @height: (out) (allow-none): return location for the height, or %NULL
* *
* Retrieves the size of @box * Retrieves the size of @box
*
* Since: 1.0
*/ */
void void
clutter_actor_box_get_size (const ClutterActorBox *box, clutter_actor_box_get_size (const ClutterActorBox *box,
@@ -276,6 +302,8 @@ clutter_actor_box_get_size (const ClutterActorBox *box,
* Retrieves the area of @box * Retrieves the area of @box
* *
* Return value: the area of a #ClutterActorBox, in pixels * Return value: the area of a #ClutterActorBox, in pixels
*
* Since: 1.0
*/ */
gfloat gfloat
clutter_actor_box_get_area (const ClutterActorBox *box) clutter_actor_box_get_area (const ClutterActorBox *box)
@@ -292,9 +320,11 @@ clutter_actor_box_get_area (const ClutterActorBox *box)
* @y: Y coordinate of the point * @y: Y coordinate of the point
* *
* Checks whether a point with @x, @y coordinates is contained * Checks whether a point with @x, @y coordinates is contained
* within @box * withing @box
* *
* Return value: %TRUE if the point is contained by the #ClutterActorBox * Return value: %TRUE if the point is contained by the #ClutterActorBox
*
* Since: 1.0
*/ */
gboolean gboolean
clutter_actor_box_contains (const ClutterActorBox *box, clutter_actor_box_contains (const ClutterActorBox *box,
@@ -310,14 +340,16 @@ clutter_actor_box_contains (const ClutterActorBox *box,
/** /**
* clutter_actor_box_from_vertices: * clutter_actor_box_from_vertices:
* @box: a #ClutterActorBox * @box: a #ClutterActorBox
* @verts: (array fixed-size=4): array of four #graphene_point3d_t * @verts: (array fixed-size=4): array of four #ClutterVertex
* *
* Calculates the bounding box represented by the four vertices; for details * Calculates the bounding box represented by the four vertices; for details
* of the vertex array see [method@Actor.get_abs_allocation_vertices]. * of the vertex array see clutter_actor_get_abs_allocation_vertices().
*
* Since: 1.0
*/ */
void void
clutter_actor_box_from_vertices (ClutterActorBox *box, clutter_actor_box_from_vertices (ClutterActorBox *box,
const graphene_point3d_t verts[]) const ClutterVertex verts[])
{ {
gfloat x_1, x_2, y_1, y_2; gfloat x_1, x_2, y_1, y_2;
@@ -380,8 +412,10 @@ clutter_actor_box_from_vertices (ClutterActorBox *box,
* @progress: the interpolation progress * @progress: the interpolation progress
* @result: (out): return location for the interpolation * @result: (out): return location for the interpolation
* *
* Interpolates between @initial and @final `ClutterActorBox`es * Interpolates between @initial and @final #ClutterActorBox<!-- -->es
* using @progress * using @progress
*
* Since: 1.2
*/ */
void void
clutter_actor_box_interpolate (const ClutterActorBox *initial, clutter_actor_box_interpolate (const ClutterActorBox *initial,
@@ -404,6 +438,8 @@ clutter_actor_box_interpolate (const ClutterActorBox *initial,
* @box: (inout): the #ClutterActorBox to clamp * @box: (inout): the #ClutterActorBox to clamp
* *
* Clamps the components of @box to the nearest integer * Clamps the components of @box to the nearest integer
*
* Since: 1.2
*/ */
void void
clutter_actor_box_clamp_to_pixel (ClutterActorBox *box) clutter_actor_box_clamp_to_pixel (ClutterActorBox *box)
@@ -424,6 +460,8 @@ clutter_actor_box_clamp_to_pixel (ClutterActorBox *box)
* of @a and @b * of @a and @b
* *
* Unions the two boxes @a and @b and stores the result in @result. * Unions the two boxes @a and @b and stores the result in @result.
*
* Since: 1.4
*/ */
void void
clutter_actor_box_union (const ClutterActorBox *a, clutter_actor_box_union (const ClutterActorBox *a,
@@ -466,6 +504,8 @@ clutter_actor_box_progress (const GValue *a,
* @y: the Y coordinate of the new origin * @y: the Y coordinate of the new origin
* *
* Changes the origin of @box, maintaining the size of the #ClutterActorBox. * Changes the origin of @box, maintaining the size of the #ClutterActorBox.
*
* Since: 1.6
*/ */
void void
clutter_actor_box_set_origin (ClutterActorBox *box, clutter_actor_box_set_origin (ClutterActorBox *box,
@@ -489,6 +529,8 @@ clutter_actor_box_set_origin (ClutterActorBox *box,
* @height: the new height * @height: the new height
* *
* Sets the size of @box, maintaining the origin of the #ClutterActorBox. * Sets the size of @box, maintaining the origin of the #ClutterActorBox.
*
* Since: 1.6
*/ */
void void
clutter_actor_box_set_size (ClutterActorBox *box, clutter_actor_box_set_size (ClutterActorBox *box,
@@ -512,7 +554,7 @@ _clutter_actor_box_enlarge_for_effects (ClutterActorBox *box)
* *
* The reason this is important is because effects will use this * The reason this is important is because effects will use this
* API to determine the size of offscreen framebuffers and so for * API to determine the size of offscreen framebuffers and so for
* a fixed-size object that may be animated across the screen we * a fixed-size object that may be animated accross the screen we
* want to make sure that the stage paint-box has an equally stable * want to make sure that the stage paint-box has an equally stable
* size so that effects aren't made to continuously re-allocate * size so that effects aren't made to continuously re-allocate
* a corresponding fbo. * a corresponding fbo.
@@ -541,7 +583,7 @@ _clutter_actor_box_enlarge_for_effects (ClutterActorBox *box)
/* Now we redefine the top-left relative to the bottom right based on the /* 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 * rounded width/height determined above + a constant so that the overall
* size of the box will be stable and not dependent on the box's * size of the box will be stable and not dependant on the box's
* position. * position.
* *
* Adding 3px to the width/height will ensure we cover the maximum of * Adding 3px to the width/height will ensure we cover the maximum of
@@ -558,6 +600,8 @@ _clutter_actor_box_enlarge_for_effects (ClutterActorBox *box)
* @scale: scale factor for resizing this box * @scale: scale factor for resizing this box
* *
* Rescale the @box by provided @scale factor. * Rescale the @box by provided @scale factor.
*
* Since: 1.6
*/ */
void void
clutter_actor_box_scale (ClutterActorBox *box, clutter_actor_box_scale (ClutterActorBox *box,
@@ -571,32 +615,6 @@ clutter_actor_box_scale (ClutterActorBox *box,
box->y2 *= 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, G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterActorBox, clutter_actor_box,
clutter_actor_box_copy, clutter_actor_box_copy,
clutter_actor_box_free, clutter_actor_box_free,

View File

@@ -23,19 +23,22 @@
*/ */
/** /**
* ClutterActorMeta: * SECTION:clutter-actor-meta
* * @Title: ClutterActorMeta
* Base class of actor modifiers * @Short_Description: Base class of actor modifiers
* @See_Also: #ClutterAction, #ClutterConstraint
* *
* #ClutterActorMeta is an abstract class providing a common API for * #ClutterActorMeta is an abstract class providing a common API for
* modifiers of [class@Actor] behaviour, appearance or layout. * modifiers of #ClutterActor behaviour, appearance or layout.
* *
* A #ClutterActorMeta can only be owned by a single [class@Actor] at * A #ClutterActorMeta can only be owned by a single #ClutterActor at
* any time. * any time.
* *
* Every sub-class of #ClutterActorMeta should check if the * Every sub-class of #ClutterActorMeta should check if the
* [property@ActorMeta:enabled] property is set to %TRUE before applying * #ClutterActorMeta:enabled property is set to %TRUE before applying
* any kind of modification. * any kind of modification.
*
* #ClutterActorMeta is available since Clutter 1.4
*/ */
#include "clutter-build-config.h" #include "clutter-build-config.h"
@@ -48,7 +51,7 @@
struct _ClutterActorMetaPrivate struct _ClutterActorMetaPrivate
{ {
ClutterActor *actor; ClutterActor *actor;
gulong destroy_id; guint destroy_id;
gchar *name; gchar *name;
@@ -78,51 +81,28 @@ static void
on_actor_destroy (ClutterActor *actor, on_actor_destroy (ClutterActor *actor,
ClutterActorMeta *meta) ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv = meta->priv->actor = NULL;
clutter_actor_meta_get_instance_private (meta);
priv->actor = NULL;
} }
static void static void
clutter_actor_meta_real_set_actor (ClutterActorMeta *meta, clutter_actor_meta_real_set_actor (ClutterActorMeta *meta,
ClutterActor *actor) ClutterActor *actor)
{ {
ClutterActorMetaPrivate *priv = if (meta->priv->actor == actor)
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; return;
g_clear_signal_handler (&priv->destroy_id, priv->actor); if (meta->priv->destroy_id != 0)
{
priv->actor = actor; g_signal_handler_disconnect (meta->priv->actor, meta->priv->destroy_id);
meta->priv->destroy_id = 0;
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 meta->priv->actor = actor;
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 || if (meta->priv->actor != NULL)
!CLUTTER_ACTOR_IN_PAINT (priv->actor)); meta->priv->destroy_id = g_signal_connect (meta->priv->actor, "destroy",
G_CALLBACK (on_actor_destroy),
priv->is_enabled = is_enabled; meta);
g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ENABLED]);
} }
static void static void
@@ -155,21 +135,20 @@ clutter_actor_meta_get_property (GObject *gobject,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
ClutterActorMetaPrivate *priv = ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject);
clutter_actor_meta_get_instance_private (CLUTTER_ACTOR_META (gobject));
switch (prop_id) switch (prop_id)
{ {
case PROP_ACTOR: case PROP_ACTOR:
g_value_set_object (value, priv->actor); g_value_set_object (value, meta->priv->actor);
break; break;
case PROP_NAME: case PROP_NAME:
g_value_set_string (value, priv->name); g_value_set_string (value, meta->priv->name);
break; break;
case PROP_ENABLED: case PROP_ENABLED:
g_value_set_boolean (value, priv->is_enabled); g_value_set_boolean (value, meta->priv->is_enabled);
break; break;
default: default:
@@ -181,11 +160,10 @@ clutter_actor_meta_get_property (GObject *gobject,
static void static void
clutter_actor_meta_finalize (GObject *gobject) clutter_actor_meta_finalize (GObject *gobject)
{ {
ClutterActorMetaPrivate *priv = ClutterActorMetaPrivate *priv = CLUTTER_ACTOR_META (gobject)->priv;
clutter_actor_meta_get_instance_private (CLUTTER_ACTOR_META (gobject));
if (priv->actor != NULL) if (priv->destroy_id != 0 && priv->actor != NULL)
g_clear_signal_handler (&priv->destroy_id, priv->actor); g_signal_handler_disconnect (priv->actor, priv->destroy_id);
g_free (priv->name); g_free (priv->name);
@@ -198,25 +176,27 @@ clutter_actor_meta_class_init (ClutterActorMetaClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
klass->set_actor = clutter_actor_meta_real_set_actor; klass->set_actor = clutter_actor_meta_real_set_actor;
klass->set_enabled = clutter_actor_meta_real_set_enabled;
/** /**
* ClutterActorMeta:actor: * ClutterActorMeta:actor:
* *
* The #ClutterActor attached to the #ClutterActorMeta instance * The #ClutterActor attached to the #ClutterActorMeta instance
*
* Since: 1.4
*/ */
obj_props[PROP_ACTOR] = obj_props[PROP_ACTOR] =
g_param_spec_object ("actor", g_param_spec_object ("actor",
P_("Actor"), P_("Actor"),
P_("The actor attached to the meta"), P_("The actor attached to the meta"),
CLUTTER_TYPE_ACTOR, CLUTTER_TYPE_ACTOR,
CLUTTER_PARAM_READABLE | CLUTTER_PARAM_READABLE);
G_PARAM_EXPLICIT_NOTIFY);
/** /**
* ClutterActorMeta:name: * ClutterActorMeta:name:
* *
* The unique name to access the #ClutterActorMeta * The unique name to access the #ClutterActorMeta
*
* Since: 1.4
*/ */
obj_props[PROP_NAME] = obj_props[PROP_NAME] =
g_param_spec_string ("name", g_param_spec_string ("name",
@@ -229,6 +209,8 @@ clutter_actor_meta_class_init (ClutterActorMetaClass *klass)
* ClutterActorMeta:enabled: * ClutterActorMeta:enabled:
* *
* Whether or not the #ClutterActorMeta is enabled * Whether or not the #ClutterActorMeta is enabled
*
* Since: 1.4
*/ */
obj_props[PROP_ENABLED] = obj_props[PROP_ENABLED] =
g_param_spec_boolean ("enabled", g_param_spec_boolean ("enabled",
@@ -248,11 +230,9 @@ clutter_actor_meta_class_init (ClutterActorMetaClass *klass)
void void
clutter_actor_meta_init (ClutterActorMeta *self) clutter_actor_meta_init (ClutterActorMeta *self)
{ {
ClutterActorMetaPrivate *priv = self->priv = clutter_actor_meta_get_instance_private (self);
clutter_actor_meta_get_instance_private (self); self->priv->is_enabled = TRUE;
self->priv->priority = CLUTTER_ACTOR_META_PRIORITY_DEFAULT;
priv->is_enabled = TRUE;
priv->priority = CLUTTER_ACTOR_META_PRIORITY_DEFAULT;
} }
/** /**
@@ -263,22 +243,20 @@ clutter_actor_meta_init (ClutterActorMeta *self)
* Sets the name of @meta * Sets the name of @meta
* *
* The name can be used to identify the #ClutterActorMeta instance * The name can be used to identify the #ClutterActorMeta instance
*
* Since: 1.4
*/ */
void void
clutter_actor_meta_set_name (ClutterActorMeta *meta, clutter_actor_meta_set_name (ClutterActorMeta *meta,
const gchar *name) const gchar *name)
{ {
ClutterActorMetaPrivate *priv;
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta)); g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
priv = clutter_actor_meta_get_instance_private (meta); if (g_strcmp0 (meta->priv->name, name) == 0)
if (g_strcmp0 (priv->name, name) == 0)
return; return;
g_free (priv->name); g_free (meta->priv->name);
priv->name = g_strdup (name); meta->priv->name = g_strdup (name);
g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_NAME]); g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_NAME]);
} }
@@ -287,23 +265,21 @@ clutter_actor_meta_set_name (ClutterActorMeta *meta,
* clutter_actor_meta_get_name: * clutter_actor_meta_get_name:
* @meta: a #ClutterActorMeta * @meta: a #ClutterActorMeta
* *
* Retrieves the name set using [method@ActorMeta.set_name] * Retrieves the name set using clutter_actor_meta_set_name()
* *
* Return value: (transfer none): the name of the #ClutterActorMeta * Return value: (transfer none): the name of the #ClutterActorMeta
* instance, or %NULL if none was set. The returned string is owned * instance, or %NULL if none was set. The returned string is owned
* by the #ClutterActorMeta instance and it should not be modified * by the #ClutterActorMeta instance and it should not be modified
* or freed * or freed
*
* Since: 1.4
*/ */
const gchar * const gchar *
clutter_actor_meta_get_name (ClutterActorMeta *meta) clutter_actor_meta_get_name (ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv;
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL); g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
priv = clutter_actor_meta_get_instance_private (meta); return meta->priv->name;
return priv->name;
} }
/** /**
@@ -312,22 +288,23 @@ clutter_actor_meta_get_name (ClutterActorMeta *meta)
* @is_enabled: whether @meta is enabled * @is_enabled: whether @meta is enabled
* *
* Sets whether @meta should be enabled or not * Sets whether @meta should be enabled or not
*
* Since: 1.4
*/ */
void void
clutter_actor_meta_set_enabled (ClutterActorMeta *meta, clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
gboolean is_enabled) gboolean is_enabled)
{ {
ClutterActorMetaPrivate *priv;
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta)); g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
priv = clutter_actor_meta_get_instance_private (meta);
is_enabled = !!is_enabled; is_enabled = !!is_enabled;
if (priv->is_enabled == is_enabled) if (meta->priv->is_enabled == is_enabled)
return; return;
CLUTTER_ACTOR_META_GET_CLASS (meta)->set_enabled (meta, is_enabled); meta->priv->is_enabled = is_enabled;
g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ENABLED]);
} }
/** /**
@@ -337,17 +314,15 @@ clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
* Retrieves whether @meta is enabled * Retrieves whether @meta is enabled
* *
* Return value: %TRUE if the #ClutterActorMeta instance is enabled * Return value: %TRUE if the #ClutterActorMeta instance is enabled
*
* Since: 1.4
*/ */
gboolean gboolean
clutter_actor_meta_get_enabled (ClutterActorMeta *meta) clutter_actor_meta_get_enabled (ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv;
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), FALSE); g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), FALSE);
priv = clutter_actor_meta_get_instance_private (meta); return meta->priv->is_enabled;
return priv->is_enabled;
} }
/* /*
@@ -357,6 +332,8 @@ clutter_actor_meta_get_enabled (ClutterActorMeta *meta)
* *
* Sets or unsets a back pointer to the #ClutterActor that owns * Sets or unsets a back pointer to the #ClutterActor that owns
* the @meta * the @meta
*
* Since: 1.4
*/ */
void void
_clutter_actor_meta_set_actor (ClutterActorMeta *meta, _clutter_actor_meta_set_actor (ClutterActorMeta *meta,
@@ -372,61 +349,49 @@ _clutter_actor_meta_set_actor (ClutterActorMeta *meta,
* clutter_actor_meta_get_actor: * clutter_actor_meta_get_actor:
* @meta: a #ClutterActorMeta * @meta: a #ClutterActorMeta
* *
* Retrieves a pointer to the [class@Actor] that owns @meta * Retrieves a pointer to the #ClutterActor that owns @meta
* *
* Return value: (transfer none): a pointer to a #ClutterActor or %NULL * Return value: (transfer none): a pointer to a #ClutterActor or %NULL
*
* Since: 1.4
*/ */
ClutterActor * ClutterActor *
clutter_actor_meta_get_actor (ClutterActorMeta *meta) clutter_actor_meta_get_actor (ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv;
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL); g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
priv = clutter_actor_meta_get_instance_private (meta); return meta->priv->actor;
return priv->actor;
} }
void void
_clutter_actor_meta_set_priority (ClutterActorMeta *meta, _clutter_actor_meta_set_priority (ClutterActorMeta *meta,
gint priority) gint priority)
{ {
ClutterActorMetaPrivate *priv;
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta)); 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 /* This property shouldn't be modified after the actor meta is in
use because ClutterMetaGroup doesn't resort the list when it use because ClutterMetaGroup doesn't resort the list when it
changes. If we made the priority public then we could either make changes. If we made the priority public then we could either make
the priority a construct-only property or listen for the priority a construct-only property or listen for
notifications on the property from the ClutterMetaGroup and notifications on the property from the ClutterMetaGroup and
resort. */ resort. */
g_return_if_fail (priv->actor == NULL); g_return_if_fail (meta->priv->actor == NULL);
priv->priority = priority; meta->priv->priority = priority;
} }
gint gint
_clutter_actor_meta_get_priority (ClutterActorMeta *meta) _clutter_actor_meta_get_priority (ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv;
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), 0); g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), 0);
priv = clutter_actor_meta_get_instance_private (meta); return meta->priv->priority;
return priv->priority;
} }
gboolean gboolean
_clutter_actor_meta_is_internal (ClutterActorMeta *meta) _clutter_actor_meta_is_internal (ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv = gint priority = meta->priv->priority;
clutter_actor_meta_get_instance_private (meta);
gint priority = priv->priority;
return (priority <= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_LOW || return (priority <= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_LOW ||
priority >= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_HIGH); priority >= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_HIGH);
@@ -473,21 +438,19 @@ void
_clutter_meta_group_add_meta (ClutterMetaGroup *group, _clutter_meta_group_add_meta (ClutterMetaGroup *group,
ClutterActorMeta *meta) ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv =
clutter_actor_meta_get_instance_private (meta);
GList *prev = NULL, *l; GList *prev = NULL, *l;
if (priv->actor != NULL) if (meta->priv->actor != NULL)
{ {
g_warning ("The meta of type '%s' with name '%s' is " g_warning ("The meta of type '%s' with name '%s' is "
"already attached to actor '%s'", "already attached to actor '%s'",
G_OBJECT_TYPE_NAME (meta), G_OBJECT_TYPE_NAME (meta),
priv->name != NULL meta->priv->name != NULL
? priv->name ? meta->priv->name
: "<unknown>", : "<unknown>",
clutter_actor_get_name (priv->actor) != NULL clutter_actor_get_name (meta->priv->actor) != NULL
? clutter_actor_get_name (priv->actor) ? clutter_actor_get_name (meta->priv->actor)
: G_OBJECT_TYPE_NAME (priv->actor)); : G_OBJECT_TYPE_NAME (meta->priv->actor));
return; return;
} }
@@ -523,16 +486,13 @@ void
_clutter_meta_group_remove_meta (ClutterMetaGroup *group, _clutter_meta_group_remove_meta (ClutterMetaGroup *group,
ClutterActorMeta *meta) ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv = if (meta->priv->actor != group->actor)
clutter_actor_meta_get_instance_private (meta);
if (priv->actor != group->actor)
{ {
g_warning ("The meta of type '%s' with name '%s' is not " g_warning ("The meta of type '%s' with name '%s' is not "
"attached to the actor '%s'", "attached to the actor '%s'",
G_OBJECT_TYPE_NAME (meta), G_OBJECT_TYPE_NAME (meta),
priv->name != NULL meta->priv->name != NULL
? priv->name ? meta->priv->name
: "<unknown>", : "<unknown>",
clutter_actor_get_name (group->actor) != NULL clutter_actor_get_name (group->actor) != NULL
? clutter_actor_get_name (group->actor) ? clutter_actor_get_name (group->actor)
@@ -675,10 +635,8 @@ _clutter_meta_group_get_meta (ClutterMetaGroup *group,
for (l = group->meta; l != NULL; l = l->next) for (l = group->meta; l != NULL; l = l->next)
{ {
ClutterActorMeta *meta = l->data; ClutterActorMeta *meta = l->data;
ClutterActorMetaPrivate *priv =
clutter_actor_meta_get_instance_private (meta);
if (g_strcmp0 (priv->name, name) == 0) if (g_strcmp0 (meta->priv->name, name) == 0)
return meta; return meta;
} }
@@ -698,8 +656,6 @@ _clutter_meta_group_get_meta (ClutterMetaGroup *group,
const gchar * const gchar *
_clutter_actor_meta_get_debug_name (ClutterActorMeta *meta) _clutter_actor_meta_get_debug_name (ClutterActorMeta *meta)
{ {
ClutterActorMetaPrivate *priv = return meta->priv->name != NULL ? meta->priv->name
clutter_actor_meta_get_instance_private (meta); : G_OBJECT_TYPE_NAME (meta);
return priv->name != NULL ? priv->name : G_OBJECT_TYPE_NAME (meta);
} }

View File

@@ -34,12 +34,30 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define CLUTTER_TYPE_ACTOR_META (clutter_actor_meta_get_type ()) #define CLUTTER_TYPE_ACTOR_META (clutter_actor_meta_get_type ())
#define CLUTTER_ACTOR_META(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMeta))
CLUTTER_EXPORT #define CLUTTER_IS_ACTOR_META(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTOR_META))
G_DECLARE_DERIVABLE_TYPE (ClutterActorMeta, clutter_actor_meta, #define CLUTTER_ACTOR_META_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass))
CLUTTER, ACTOR_META, GInitiallyUnowned); #define CLUTTER_IS_ACTOR_META_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTOR_META))
#define CLUTTER_ACTOR_META_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass))
typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate; typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate;
typedef struct _ClutterActorMetaClass ClutterActorMetaClass;
/**
* ClutterActorMeta:
*
* The #ClutterActorMeta structure contains only
* private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _ClutterActorMeta
{
/*< private >*/
GInitiallyUnowned parent_instance;
ClutterActorMetaPrivate *priv;
};
/** /**
* ClutterActorMetaClass: * ClutterActorMetaClass:
@@ -48,6 +66,8 @@ typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate;
* *
* The #ClutterActorMetaClass structure contains * The #ClutterActorMetaClass structure contains
* only private data * only private data
*
* Since: 1.4
*/ */
struct _ClutterActorMetaClass struct _ClutterActorMetaClass
{ {
@@ -67,9 +87,6 @@ struct _ClutterActorMetaClass
void (* set_actor) (ClutterActorMeta *meta, void (* set_actor) (ClutterActorMeta *meta,
ClutterActor *actor); ClutterActor *actor);
void (* set_enabled) (ClutterActorMeta *meta,
gboolean is_enabled);
/*< private >*/ /*< private >*/
void (* _clutter_meta1) (void); void (* _clutter_meta1) (void);
void (* _clutter_meta2) (void); void (* _clutter_meta2) (void);
@@ -77,8 +94,12 @@ struct _ClutterActorMetaClass
void (* _clutter_meta4) (void); void (* _clutter_meta4) (void);
void (* _clutter_meta5) (void); void (* _clutter_meta5) (void);
void (* _clutter_meta6) (void); void (* _clutter_meta6) (void);
void (* _clutter_meta7) (void);
}; };
CLUTTER_EXPORT
GType clutter_actor_meta_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_meta_set_name (ClutterActorMeta *meta, void clutter_actor_meta_set_name (ClutterActorMeta *meta,
const gchar *name); const gchar *name);

View File

@@ -23,10 +23,26 @@
#define __CLUTTER_ACTOR_PRIVATE_H__ #define __CLUTTER_ACTOR_PRIVATE_H__
#include <clutter/clutter-actor.h> #include <clutter/clutter-actor.h>
#include <clutter/clutter-grab.h>
G_BEGIN_DECLS G_BEGIN_DECLS
/*< private >
* ClutterRedrawFlags:
* @CLUTTER_REDRAW_CLIPPED_TO_ALLOCATION: Tells clutter the maximum
* extents of what needs to be redrawn lies within the actors
* current allocation. (Only use this for 2D actors though because
* any actor with depth may be projected outside of its allocation)
*
* Flags passed to the clutter_actor_queue_redraw_with_clip ()
* function
*
* Since: 1.6
*/
typedef enum
{
CLUTTER_REDRAW_CLIPPED_TO_ALLOCATION = 1 << 0
} ClutterRedrawFlags;
/*< private > /*< private >
* ClutterActorTraverseFlags: * ClutterActorTraverseFlags:
* CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST: Traverse the graph in * CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST: Traverse the graph in
@@ -94,12 +110,35 @@ typedef ClutterActorTraverseVisitFlags (*ClutterTraverseCallback) (ClutterActor
typedef gboolean (*ClutterForeachCallback) (ClutterActor *actor, typedef gboolean (*ClutterForeachCallback) (ClutterActor *actor,
gpointer user_data); gpointer user_data);
typedef struct _AnchorCoord AnchorCoord;
typedef struct _SizeRequest SizeRequest; typedef struct _SizeRequest SizeRequest;
typedef struct _ClutterLayoutInfo ClutterLayoutInfo; typedef struct _ClutterLayoutInfo ClutterLayoutInfo;
typedef struct _ClutterTransformInfo ClutterTransformInfo; typedef struct _ClutterTransformInfo ClutterTransformInfo;
typedef struct _ClutterAnimationInfo ClutterAnimationInfo; typedef struct _ClutterAnimationInfo ClutterAnimationInfo;
/* Internal helper struct to represent a point that can be stored in
either direct pixel coordinates or as a fraction of the actor's
size. It is used for the anchor point, scale center and rotation
centers. */
struct _AnchorCoord
{
gboolean is_fractional;
union
{
/* Used when is_fractional == TRUE */
struct
{
gdouble x;
gdouble y;
} fraction;
/* Use when is_fractional == FALSE */
ClutterVertex units;
} v;
};
struct _SizeRequest struct _SizeRequest
{ {
guint age; guint age;
@@ -124,7 +163,7 @@ struct _SizeRequest
struct _ClutterLayoutInfo struct _ClutterLayoutInfo
{ {
/* fixed position coordinates */ /* fixed position coordinates */
graphene_point_t fixed_pos; ClutterPoint fixed_pos;
ClutterMargin margin; ClutterMargin margin;
@@ -134,8 +173,8 @@ struct _ClutterLayoutInfo
guint x_expand : 1; guint x_expand : 1;
guint y_expand : 1; guint y_expand : 1;
graphene_size_t minimum; ClutterSize minimum;
graphene_size_t natural; ClutterSize natural;
}; };
const ClutterLayoutInfo * _clutter_actor_get_layout_info_or_defaults (ClutterActor *self); const ClutterLayoutInfo * _clutter_actor_get_layout_info_or_defaults (ClutterActor *self);
@@ -144,30 +183,39 @@ ClutterLayoutInfo * _clutter_actor_peek_layout_info
struct _ClutterTransformInfo struct _ClutterTransformInfo
{ {
/* rotation */ /* rotation (angle and center) */
gdouble rx_angle; gdouble rx_angle;
AnchorCoord rx_center;
gdouble ry_angle; gdouble ry_angle;
AnchorCoord ry_center;
gdouble rz_angle; gdouble rz_angle;
AnchorCoord rz_center;
/* scaling */ /* scaling */
gdouble scale_x; gdouble scale_x;
gdouble scale_y; gdouble scale_y;
gdouble scale_z; gdouble scale_z;
AnchorCoord scale_center;
/* anchor point */
AnchorCoord anchor;
/* translation */ /* translation */
graphene_point3d_t translation; ClutterVertex translation;
/* z_position */ /* z_position */
gfloat z_position; gfloat z_position;
/* transformation center */ /* transformation center */
graphene_point_t pivot; ClutterPoint pivot;
gfloat pivot_z; gfloat pivot_z;
graphene_matrix_t transform; CoglMatrix transform;
guint transform_set : 1; guint transform_set : 1;
graphene_matrix_t child_transform; CoglMatrix child_transform;
guint child_transform_set : 1; guint child_transform_set : 1;
}; };
@@ -194,6 +242,9 @@ ClutterAnimationInfo * _clutter_actor_get_animation_info
ClutterTransition * _clutter_actor_create_transition (ClutterActor *self, ClutterTransition * _clutter_actor_create_transition (ClutterActor *self,
GParamSpec *pspec, GParamSpec *pspec,
...); ...);
ClutterTransition * _clutter_actor_get_transition (ClutterActor *self,
GParamSpec *pspec);
gboolean _clutter_actor_foreach_child (ClutterActor *self, gboolean _clutter_actor_foreach_child (ClutterActor *self,
ClutterForeachCallback callback, ClutterForeachCallback callback,
gpointer user_data); gpointer user_data);
@@ -205,10 +256,10 @@ void _clutter_actor_traverse
ClutterActor * _clutter_actor_get_stage_internal (ClutterActor *actor); ClutterActor * _clutter_actor_get_stage_internal (ClutterActor *actor);
void _clutter_actor_apply_modelview_transform (ClutterActor *self, void _clutter_actor_apply_modelview_transform (ClutterActor *self,
graphene_matrix_t *matrix); CoglMatrix *matrix);
void _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self, void _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self,
ClutterActor *ancestor, ClutterActor *ancestor,
graphene_matrix_t *matrix); CoglMatrix *matrix);
void _clutter_actor_rerealize (ClutterActor *self, void _clutter_actor_rerealize (ClutterActor *self,
ClutterCallback callback, ClutterCallback callback,
@@ -226,58 +277,51 @@ void _clutter_actor_set_enable_paint_unmapped
void _clutter_actor_set_has_pointer (ClutterActor *self, void _clutter_actor_set_has_pointer (ClutterActor *self,
gboolean has_pointer); gboolean has_pointer);
void _clutter_actor_set_has_key_focus (ClutterActor *self, void _clutter_actor_queue_redraw_with_clip (ClutterActor *self,
gboolean has_key_focus); ClutterRedrawFlags flags,
const ClutterPaintVolume *clip_volume);
void _clutter_actor_queue_redraw_full (ClutterActor *self, void _clutter_actor_queue_redraw_full (ClutterActor *self,
ClutterRedrawFlags flags,
const ClutterPaintVolume *volume, const ClutterPaintVolume *volume,
ClutterEffect *effect); ClutterEffect *effect);
void _clutter_actor_finish_queue_redraw (ClutterActor *self); void _clutter_actor_finish_queue_redraw (ClutterActor *self,
ClutterPaintVolume *clip);
gboolean _clutter_actor_set_default_paint_volume (ClutterActor *self, gboolean _clutter_actor_set_default_paint_volume (ClutterActor *self,
GType check_gtype, GType check_gtype,
ClutterPaintVolume *volume); ClutterPaintVolume *volume);
const char * _clutter_actor_get_debug_name (ClutterActor *self); const gchar * _clutter_actor_get_debug_name (ClutterActor *self);
void _clutter_actor_push_clone_paint (void); void _clutter_actor_push_clone_paint (void);
void _clutter_actor_pop_clone_paint (void); void _clutter_actor_pop_clone_paint (void);
void _clutter_actor_shader_pre_paint (ClutterActor *actor,
gboolean repeat);
void _clutter_actor_shader_post_paint (ClutterActor *actor);
ClutterActorAlign _clutter_actor_get_effective_x_align (ClutterActor *self); ClutterActorAlign _clutter_actor_get_effective_x_align (ClutterActor *self);
void _clutter_actor_handle_event (ClutterActor *actor, void _clutter_actor_handle_event (ClutterActor *actor,
ClutterActor *root,
const ClutterEvent *event); const ClutterEvent *event);
void _clutter_actor_attach_clone (ClutterActor *actor, void _clutter_actor_attach_clone (ClutterActor *actor,
ClutterActor *clone); ClutterActor *clone);
void _clutter_actor_detach_clone (ClutterActor *actor, void _clutter_actor_detach_clone (ClutterActor *actor,
ClutterActor *clone); ClutterActor *clone);
void _clutter_actor_queue_redraw_on_clones (ClutterActor *actor);
void _clutter_actor_queue_relayout_on_clones (ClutterActor *actor);
void _clutter_actor_queue_only_relayout (ClutterActor *actor); void _clutter_actor_queue_only_relayout (ClutterActor *actor);
void clutter_actor_clear_stage_views_recursive (ClutterActor *actor); void _clutter_actor_queue_update_resource_scale_recursive (ClutterActor *actor);
float clutter_actor_get_real_resource_scale (ClutterActor *actor); CoglFramebuffer * _clutter_actor_get_active_framebuffer (ClutterActor *actor);
gboolean _clutter_actor_get_real_resource_scale (ClutterActor *actor,
float *resource_scale);
ClutterPaintNode * clutter_actor_create_texture_paint_node (ClutterActor *self, ClutterPaintNode * clutter_actor_create_texture_paint_node (ClutterActor *self,
CoglTexture *texture); CoglTexture *texture);
void clutter_actor_finish_layout (ClutterActor *self,
int phase);
void clutter_actor_queue_immediate_relayout (ClutterActor *self);
gboolean clutter_actor_is_painting_unmapped (ClutterActor *self);
gboolean clutter_actor_get_redraw_clip (ClutterActor *self,
ClutterPaintVolume *dst_old_pv,
ClutterPaintVolume *dst_new_pv);
void clutter_actor_attach_grab (ClutterActor *actor,
ClutterGrab *grab);
void clutter_actor_detach_grab (ClutterActor *actor,
ClutterGrab *grab);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_ACTOR_PRIVATE_H__ */ #endif /* __CLUTTER_ACTOR_PRIVATE_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -39,8 +39,6 @@
#include <clutter/clutter-types.h> #include <clutter/clutter-types.h>
#include <clutter/clutter-event.h> #include <clutter/clutter-event.h>
#include <clutter/clutter-paint-context.h>
#include <clutter/clutter-pick-context.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@@ -118,7 +116,12 @@ typedef void (*ClutterCallback) (ClutterActor *actor,
*/ */
#define CLUTTER_CALLBACK(f) ((ClutterCallback) (f)) #define CLUTTER_CALLBACK(f) ((ClutterCallback) (f))
/**
* ClutterActor:
* @flags: #ClutterActorFlags
*
* Base class for actors.
*/
struct _ClutterActor struct _ClutterActor
{ {
/*< private >*/ /*< private >*/
@@ -137,6 +140,11 @@ struct _ClutterActor
* ClutterActorClass: * ClutterActorClass:
* @show: signal class handler for #ClutterActor::show; it must chain * @show: signal class handler for #ClutterActor::show; it must chain
* up to the parent's implementation * up to the parent's implementation
* @show_all: virtual function for containers and composite actors, to
* determine which children should be shown when calling
* clutter_actor_show_all() on the actor. Defaults to calling
* clutter_actor_show(). This virtual function is deprecated and it
* should not be overridden.
* @hide: signal class handler for #ClutterActor::hide; it must chain * @hide: signal class handler for #ClutterActor::hide; it must chain
* up to the parent's implementation * up to the parent's implementation
* @hide_all: virtual function for containers and composite actors, to * @hide_all: virtual function for containers and composite actors, to
@@ -165,23 +173,18 @@ struct _ClutterActor
* @get_preferred_height: virtual function, used when querying the minimum * @get_preferred_height: virtual function, used when querying the minimum
* and natural heights of an actor for a given width; it is used by * and natural heights of an actor for a given width; it is used by
* clutter_actor_get_preferred_height() * clutter_actor_get_preferred_height()
* @allocate: virtual function, used when setting the coordinates of an * @allocate: virtual function, used when settings the coordinates of an
* actor; it is used by clutter_actor_allocate(); when overriding this * actor; it is used by clutter_actor_allocate(); it must chain up to
* function without chaining up, clutter_actor_set_allocation() must be * the parent's implementation, or call clutter_actor_set_allocation()
* 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 * @apply_transform: virtual function, used when applying the transformations
* to an actor before painting it or when transforming coordinates or * to an actor before painting it or when transforming coordinates or
* the allocation; if the transformation calculated by this function may * the allocation; it must chain up to the parent's implementation
* 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 #ClutterActor::parent-set * @parent_set: signal class handler for the #ClutterActor::parent-set
* @destroy: signal class handler for #ClutterActor::destroy. It must * @destroy: signal class handler for #ClutterActor::destroy. It must
* chain up to the parent's implementation * chain up to the parent's implementation
* @pick: virtual function, used to draw an outline of the actor with * @pick: virtual function, used to draw an outline of the actor with
* the given color * the given color
* @queue_redraw: class handler for #ClutterActor::queue-redraw
* @event: class handler for #ClutterActor::event * @event: class handler for #ClutterActor::event
* @button_press_event: class handler for #ClutterActor::button-press-event * @button_press_event: class handler for #ClutterActor::button-press-event
* @button_release_event: class handler for * @button_release_event: class handler for
@@ -218,20 +221,24 @@ struct _ClutterActorClass
/*< public >*/ /*< public >*/
void (* show) (ClutterActor *self); void (* show) (ClutterActor *self);
void (* show_all) (ClutterActor *self);
void (* hide) (ClutterActor *self); void (* hide) (ClutterActor *self);
void (* hide_all) (ClutterActor *self); void (* hide_all) (ClutterActor *self);
void (* realize) (ClutterActor *self); void (* realize) (ClutterActor *self);
void (* unrealize) (ClutterActor *self); void (* unrealize) (ClutterActor *self);
void (* map) (ClutterActor *self); void (* map) (ClutterActor *self);
void (* unmap) (ClutterActor *self); void (* unmap) (ClutterActor *self);
void (* paint) (ClutterActor *self, void (* paint) (ClutterActor *self);
ClutterPaintContext *paint_context);
void (* parent_set) (ClutterActor *actor, void (* parent_set) (ClutterActor *actor,
ClutterActor *old_parent); ClutterActor *old_parent);
void (* destroy) (ClutterActor *self); void (* destroy) (ClutterActor *self);
void (* pick) (ClutterActor *actor, void (* pick) (ClutterActor *actor,
ClutterPickContext *pick_context); const ClutterColor *color);
gboolean (* queue_redraw) (ClutterActor *actor,
ClutterActor *leaf_that_queued,
ClutterPaintVolume *paint_volume);
/* size negotiation */ /* size negotiation */
void (* get_preferred_width) (ClutterActor *self, void (* get_preferred_width) (ClutterActor *self,
@@ -243,11 +250,12 @@ struct _ClutterActorClass
gfloat *min_height_p, gfloat *min_height_p,
gfloat *natural_height_p); gfloat *natural_height_p);
void (* allocate) (ClutterActor *self, void (* allocate) (ClutterActor *self,
const ClutterActorBox *box); const ClutterActorBox *box,
ClutterAllocationFlags flags);
/* transformations */ /* transformations */
void (* apply_transform) (ClutterActor *actor, void (* apply_transform) (ClutterActor *actor,
graphene_matrix_t *matrix); ClutterMatrix *matrix);
/* event signals */ /* event signals */
gboolean (* event) (ClutterActor *actor, gboolean (* event) (ClutterActor *actor,
@@ -288,14 +296,10 @@ struct _ClutterActorClass
gboolean (* touch_event) (ClutterActor *self, gboolean (* touch_event) (ClutterActor *self,
ClutterTouchEvent *event); ClutterTouchEvent *event);
gboolean (* has_accessible) (ClutterActor *self);
void (* resource_scale_changed) (ClutterActor *self);
float (* calculate_resource_scale) (ClutterActor *self,
int phase);
/*< private >*/ /*< private >*/
/* padding for future expansion */ /* padding for future expansion */
gpointer _padding_dummy[25]; gpointer _padding_dummy[26];
}; };
/** /**
@@ -306,6 +310,8 @@ struct _ClutterActorClass
* *
* The contents of the #ClutterActorIter structure * The contents of the #ClutterActorIter structure
* are private and should only be accessed using the provided API. * are private and should only be accessed using the provided API.
*
* Since: 1.10
*/ */
struct _ClutterActorIter struct _ClutterActorIter
{ {
@@ -344,17 +350,9 @@ void clutter_actor_map
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_unmap (ClutterActor *self); void clutter_actor_unmap (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_paint (ClutterActor *self, void clutter_actor_paint (ClutterActor *self);
ClutterPaintContext *paint_context);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_continue_paint (ClutterActor *self, void clutter_actor_continue_paint (ClutterActor *self);
ClutterPaintContext *paint_context);
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 CLUTTER_EXPORT
void clutter_actor_queue_redraw (ClutterActor *self); void clutter_actor_queue_redraw (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_EXPORT
@@ -371,8 +369,6 @@ CLUTTER_EXPORT
const gchar * clutter_actor_get_name (ClutterActor *self); const gchar * clutter_actor_get_name (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_EXPORT
AtkObject * clutter_actor_get_accessible (ClutterActor *self); AtkObject * clutter_actor_get_accessible (ClutterActor *self);
CLUTTER_EXPORT
gboolean clutter_actor_has_accessible (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_EXPORT
gboolean clutter_actor_is_visible (ClutterActor *self); gboolean clutter_actor_is_visible (ClutterActor *self);
@@ -405,31 +401,38 @@ void clutter_actor_get_preferred_size
gfloat *natural_height_p); gfloat *natural_height_p);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_allocate (ClutterActor *self, void clutter_actor_allocate (ClutterActor *self,
const ClutterActorBox *box); const ClutterActorBox *box,
ClutterAllocationFlags flags);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_allocate_preferred_size (ClutterActor *self, void clutter_actor_allocate_preferred_size (ClutterActor *self,
float x, ClutterAllocationFlags flags);
float y);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_allocate_available_size (ClutterActor *self, void clutter_actor_allocate_available_size (ClutterActor *self,
gfloat x, gfloat x,
gfloat y, gfloat y,
gfloat available_width, gfloat available_width,
gfloat available_height); gfloat available_height,
ClutterAllocationFlags flags);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_allocate_align_fill (ClutterActor *self, void clutter_actor_allocate_align_fill (ClutterActor *self,
const ClutterActorBox *box, const ClutterActorBox *box,
gdouble x_align, gdouble x_align,
gdouble y_align, gdouble y_align,
gboolean x_fill, gboolean x_fill,
gboolean y_fill); gboolean y_fill,
ClutterAllocationFlags flags);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_set_allocation (ClutterActor *self, void clutter_actor_set_allocation (ClutterActor *self,
const ClutterActorBox *box); const ClutterActorBox *box,
ClutterAllocationFlags flags);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_get_allocation_box (ClutterActor *self, void clutter_actor_get_allocation_box (ClutterActor *self,
ClutterActorBox *box); ClutterActorBox *box);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_get_allocation_vertices (ClutterActor *self,
ClutterActor *ancestor,
ClutterVertex verts[]);
CLUTTER_EXPORT
gboolean clutter_actor_has_allocation (ClutterActor *self); gboolean clutter_actor_has_allocation (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_set_size (ClutterActor *self, void clutter_actor_set_size (ClutterActor *self,
@@ -444,10 +447,6 @@ void clutter_actor_set_position
gfloat x, gfloat x,
gfloat y); gfloat y);
CLUTTER_EXPORT CLUTTER_EXPORT
gboolean clutter_actor_get_fixed_position (ClutterActor *self,
float *x,
float *y);
CLUTTER_EXPORT
void clutter_actor_get_position (ClutterActor *self, void clutter_actor_get_position (ClutterActor *self,
gfloat *x, gfloat *x,
gfloat *y); gfloat *y);
@@ -579,8 +578,7 @@ void clutter_actor_set_offscreen_redirect
CLUTTER_EXPORT CLUTTER_EXPORT
ClutterOffscreenRedirect clutter_actor_get_offscreen_redirect (ClutterActor *self); ClutterOffscreenRedirect clutter_actor_get_offscreen_redirect (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_EXPORT
gboolean clutter_actor_should_pick (ClutterActor *self, gboolean clutter_actor_should_pick_paint (ClutterActor *self);
ClutterPickContext *pick_context);
CLUTTER_EXPORT CLUTTER_EXPORT
gboolean clutter_actor_is_in_clone_paint (ClutterActor *self); gboolean clutter_actor_is_in_clone_paint (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_EXPORT
@@ -588,7 +586,8 @@ gboolean clutter_actor_get_paint_box
ClutterActorBox *box); ClutterActorBox *box);
CLUTTER_EXPORT CLUTTER_EXPORT
float clutter_actor_get_resource_scale (ClutterActor *self); gboolean clutter_actor_get_resource_scale (ClutterActor *self,
gfloat *resource_scale);
CLUTTER_EXPORT CLUTTER_EXPORT
gboolean clutter_actor_has_overlaps (ClutterActor *self); gboolean clutter_actor_has_overlaps (ClutterActor *self);
@@ -617,13 +616,6 @@ void clutter_actor_set_content_repeat
ClutterContentRepeat repeat); ClutterContentRepeat repeat);
CLUTTER_EXPORT CLUTTER_EXPORT
ClutterContentRepeat clutter_actor_get_content_repeat (ClutterActor *self); ClutterContentRepeat clutter_actor_get_content_repeat (ClutterActor *self);
CLUTTER_EXPORT
void clutter_actor_set_color_state (ClutterActor *self,
ClutterColorState *color_state);
CLUTTER_EXPORT
ClutterColorState *clutter_actor_get_color_state (ClutterActor *self);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_get_content_box (ClutterActor *self, void clutter_actor_get_content_box (ClutterActor *self,
ClutterActorBox *box); ClutterActorBox *box);
@@ -799,21 +791,16 @@ void clutter_actor_get_translation
gfloat *translate_z); gfloat *translate_z);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_set_transform (ClutterActor *self, void clutter_actor_set_transform (ClutterActor *self,
const graphene_matrix_t *transform); const ClutterMatrix *transform);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_get_transform (ClutterActor *self, void clutter_actor_get_transform (ClutterActor *self,
graphene_matrix_t *transform); ClutterMatrix *transform);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_set_child_transform (ClutterActor *self, void clutter_actor_set_child_transform (ClutterActor *self,
const graphene_matrix_t *transform); const ClutterMatrix *transform);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_get_child_transform (ClutterActor *self, void clutter_actor_get_child_transform (ClutterActor *self,
graphene_matrix_t *transform); ClutterMatrix *transform);
CLUTTER_EXPORT
void clutter_actor_get_transformed_extents (ClutterActor *self,
graphene_rect_t *rect);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_get_transformed_position (ClutterActor *self, void clutter_actor_get_transformed_position (ClutterActor *self,
gfloat *x, gfloat *x,
@@ -830,16 +817,16 @@ gboolean clutter_actor_transform_stage_point
gfloat *y_out); gfloat *y_out);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_get_abs_allocation_vertices (ClutterActor *self, void clutter_actor_get_abs_allocation_vertices (ClutterActor *self,
graphene_point3d_t *verts); ClutterVertex verts[]);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_apply_transform_to_point (ClutterActor *self, void clutter_actor_apply_transform_to_point (ClutterActor *self,
const graphene_point3d_t *point, const ClutterVertex *point,
graphene_point3d_t *vertex); ClutterVertex *vertex);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_apply_relative_transform_to_point (ClutterActor *self, void clutter_actor_apply_relative_transform_to_point (ClutterActor *self,
ClutterActor *ancestor, ClutterActor *ancestor,
const graphene_point3d_t *point, const ClutterVertex *point,
graphene_point3d_t *vertex); ClutterVertex *vertex);
/* Implicit animations */ /* Implicit animations */
CLUTTER_EXPORT CLUTTER_EXPORT
@@ -883,11 +870,6 @@ void clutter_actor_set_opacity_override
CLUTTER_EXPORT CLUTTER_EXPORT
gint clutter_actor_get_opacity_override (ClutterActor *self); 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: * ClutterActorCreateChildFunc:
* @item: (type GObject): the item in the model * @item: (type GObject): the item in the model
@@ -900,7 +882,9 @@ void clutter_actor_uninhibit_culling
* of interest, using g_object_bind_property(). This way, when the @item * of interest, using g_object_bind_property(). This way, when the @item
* in the #GListModel changes, the #ClutterActor changes as well. * in the #GListModel changes, the #ClutterActor changes as well.
* *
* Returns: (transfer full): The newly created child #ClutterActor4 * Returns: (transfer full): The newly created child #ClutterActor
*
* Since: 1.24
*/ */
typedef ClutterActor * (* ClutterActorCreateChildFunc) (gpointer item, typedef ClutterActor * (* ClutterActorCreateChildFunc) (gpointer item,
gpointer user_data); gpointer user_data);
@@ -920,18 +904,8 @@ void clutter_actor_bind_model_with_properties
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_pick_box (ClutterActor *self, void clutter_actor_pick_box (ClutterActor *self,
ClutterPickContext *pick_context,
const ClutterActorBox *box); const ClutterActorBox *box);
CLUTTER_EXPORT
GList * clutter_actor_peek_stage_views (ClutterActor *self);
CLUTTER_EXPORT
void clutter_actor_invalidate_transform (ClutterActor *self);
CLUTTER_EXPORT
void clutter_actor_invalidate_paint_volume (ClutterActor *self);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_ACTOR_H__ */ #endif /* __CLUTTER_ACTOR_H__ */

View File

@@ -23,13 +23,15 @@
*/ */
/** /**
* ClutterAlignConstraint: * SECTION:clutter-align-constraint
* @Title: ClutterAlignConstraint
* @Short_Description: A constraint aligning the position of an actor
* *
* A constraint aligning the position of an actor * #ClutterAlignConstraint is a #ClutterConstraint that aligns the position
* of the #ClutterActor to which it is applied to the size of another
* #ClutterActor using an alignment factor
* *
* #ClutterAlignConstraint is a [class@Constraint] that aligns the position * #ClutterAlignConstraint is available since Clutter 1.4
* of the [class@Actor] to which it is applied to the size of another
* [class@Actor] using an alignment factor
*/ */
#include "clutter-build-config.h" #include "clutter-build-config.h"
@@ -56,7 +58,6 @@ struct _ClutterAlignConstraint
ClutterActor *actor; ClutterActor *actor;
ClutterActor *source; ClutterActor *source;
ClutterAlignAxis align_axis; ClutterAlignAxis align_axis;
graphene_point_t pivot;
gfloat factor; gfloat factor;
}; };
@@ -71,7 +72,6 @@ enum
PROP_SOURCE, PROP_SOURCE,
PROP_ALIGN_AXIS, PROP_ALIGN_AXIS,
PROP_PIVOT_POINT,
PROP_FACTOR, PROP_FACTOR,
PROP_LAST PROP_LAST
@@ -84,11 +84,13 @@ G_DEFINE_TYPE (ClutterAlignConstraint,
CLUTTER_TYPE_CONSTRAINT); CLUTTER_TYPE_CONSTRAINT);
static void static void
source_queue_relayout (ClutterActor *actor, source_position_changed (ClutterActor *actor,
const ClutterActorBox *allocation,
ClutterAllocationFlags flags,
ClutterAlignConstraint *align) ClutterAlignConstraint *align)
{ {
if (align->actor != NULL) if (align->actor != NULL)
_clutter_actor_queue_only_relayout (align->actor); clutter_actor_queue_relayout (align->actor);
} }
static void static void
@@ -133,41 +135,35 @@ clutter_align_constraint_update_allocation (ClutterConstraint *constraint,
ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (constraint); ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (constraint);
gfloat source_width, source_height; gfloat source_width, source_height;
gfloat actor_width, actor_height; gfloat actor_width, actor_height;
gfloat offset_x_start, offset_y_start; gfloat source_x, source_y;
gfloat pivot_x, pivot_y;
if (align->source == NULL) if (align->source == NULL)
return; return;
clutter_actor_box_get_size (allocation, &actor_width, &actor_height); clutter_actor_box_get_size (allocation, &actor_width, &actor_height);
clutter_actor_get_position (align->source, &source_x, &source_y);
clutter_actor_get_size (align->source, &source_width, &source_height); 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) switch (align->align_axis)
{ {
case CLUTTER_ALIGN_X_AXIS: case CLUTTER_ALIGN_X_AXIS:
allocation->x1 += offset_x_start + (source_width * align->factor); allocation->x1 = ((source_width - actor_width) * align->factor)
+ source_x;
allocation->x2 = allocation->x1 + actor_width; allocation->x2 = allocation->x1 + actor_width;
break; break;
case CLUTTER_ALIGN_Y_AXIS: case CLUTTER_ALIGN_Y_AXIS:
allocation->y1 += offset_y_start + (source_height * align->factor); allocation->y1 = ((source_height - actor_height) * align->factor)
+ source_y;
allocation->y2 = allocation->y1 + actor_height; allocation->y2 = allocation->y1 + actor_height;
break; break;
case CLUTTER_ALIGN_BOTH: case CLUTTER_ALIGN_BOTH:
allocation->x1 += offset_x_start + (source_width * align->factor); allocation->x1 = ((source_width - actor_width) * align->factor)
allocation->y1 += offset_y_start + (source_height * align->factor); + source_x;
allocation->y1 = ((source_height - actor_height) * align->factor)
+ source_y;
allocation->x2 = allocation->x1 + actor_width; allocation->x2 = allocation->x1 + actor_width;
allocation->y2 = allocation->y1 + actor_height; allocation->y2 = allocation->y1 + actor_height;
break; break;
@@ -191,7 +187,7 @@ clutter_align_constraint_dispose (GObject *gobject)
G_CALLBACK (source_destroyed), G_CALLBACK (source_destroyed),
align); align);
g_signal_handlers_disconnect_by_func (align->source, g_signal_handlers_disconnect_by_func (align->source,
G_CALLBACK (source_queue_relayout), G_CALLBACK (source_position_changed),
align); align);
align->source = NULL; align->source = NULL;
} }
@@ -217,10 +213,6 @@ clutter_align_constraint_set_property (GObject *gobject,
clutter_align_constraint_set_align_axis (align, g_value_get_enum (value)); clutter_align_constraint_set_align_axis (align, g_value_get_enum (value));
break; break;
case PROP_PIVOT_POINT:
clutter_align_constraint_set_pivot_point (align, g_value_get_boxed (value));
break;
case PROP_FACTOR: case PROP_FACTOR:
clutter_align_constraint_set_factor (align, g_value_get_float (value)); clutter_align_constraint_set_factor (align, g_value_get_float (value));
break; break;
@@ -249,16 +241,6 @@ clutter_align_constraint_get_property (GObject *gobject,
g_value_set_enum (value, align->align_axis); g_value_set_enum (value, align->align_axis);
break; 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: case PROP_FACTOR:
g_value_set_float (value, align->factor); g_value_set_float (value, align->factor);
break; break;
@@ -287,6 +269,8 @@ clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass)
* *
* The #ClutterActor must not be a child or a grandchild of the actor * The #ClutterActor must not be a child or a grandchild of the actor
* using the constraint. * using the constraint.
*
* Since: 1.4
*/ */
obj_props[PROP_SOURCE] = obj_props[PROP_SOURCE] =
g_param_spec_object ("source", g_param_spec_object ("source",
@@ -299,6 +283,8 @@ clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass)
* ClutterAlignConstraint:align-axis: * ClutterAlignConstraint:align-axis:
* *
* The axis to be used to compute the alignment * The axis to be used to compute the alignment
*
* Since: 1.4
*/ */
obj_props[PROP_ALIGN_AXIS] = obj_props[PROP_ALIGN_AXIS] =
g_param_spec_enum ("align-axis", g_param_spec_enum ("align-axis",
@@ -308,30 +294,6 @@ clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass)
CLUTTER_ALIGN_X_AXIS, CLUTTER_ALIGN_X_AXIS,
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT); CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT);
/**
* ClutterAlignConstraint:pivot-point:
*
* The pivot point used by the constraint. The pivot point is the
* point in the constraint actor around which the aligning is applied,
* with (0, 0) being the top left corner of the actor and (1, 1) the
* bottom right corner of the actor.
*
* For example, setting the pivot point to (0.5, 0.5) and using a factor
* of 1 for both axes will align the actors horizontal and vertical
* center point with the bottom right corner of the source actor.
*
* By default, the pivot point is set to (-1, -1), which means it's not
* used and the constrained actor will be aligned to always stay inside
* the source actor.
*/
obj_props[PROP_PIVOT_POINT] =
g_param_spec_boxed ("pivot-point",
P_("Pivot point"),
P_("The pivot point"),
GRAPHENE_TYPE_POINT,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/** /**
* ClutterAlignConstraint:factor: * ClutterAlignConstraint:factor:
* *
@@ -341,6 +303,8 @@ clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass)
* with an align-axis value of %CLUTTER_ALIGN_X_AXIS, 0.0 means left and * 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 * 1.0 means right; with a value of %CLUTTER_ALIGN_Y_AXIS, 0.0 means top
* and 1.0 means bottom. * and 1.0 means bottom.
*
* Since: 1.4
*/ */
obj_props[PROP_FACTOR] = obj_props[PROP_FACTOR] =
g_param_spec_float ("factor", g_param_spec_float ("factor",
@@ -362,8 +326,6 @@ clutter_align_constraint_init (ClutterAlignConstraint *self)
self->actor = NULL; self->actor = NULL;
self->source = NULL; self->source = NULL;
self->align_axis = CLUTTER_ALIGN_X_AXIS; self->align_axis = CLUTTER_ALIGN_X_AXIS;
self->pivot.x = -1.f;
self->pivot.y = -1.f;
self->factor = 0.0f; self->factor = 0.0f;
} }
@@ -379,6 +341,8 @@ clutter_align_constraint_init (ClutterAlignConstraint *self)
* alignment @factor * alignment @factor
* *
* Return value: the newly created #ClutterAlignConstraint * Return value: the newly created #ClutterAlignConstraint
*
* Since: 1.4
*/ */
ClutterConstraint * ClutterConstraint *
clutter_align_constraint_new (ClutterActor *source, clutter_align_constraint_new (ClutterActor *source,
@@ -400,6 +364,8 @@ clutter_align_constraint_new (ClutterActor *source,
* @source: (allow-none): a #ClutterActor, or %NULL to unset the source * @source: (allow-none): a #ClutterActor, or %NULL to unset the source
* *
* Sets the source of the alignment constraint * Sets the source of the alignment constraint
*
* Since: 1.4
*/ */
void void
clutter_align_constraint_set_source (ClutterAlignConstraint *align, clutter_align_constraint_set_source (ClutterAlignConstraint *align,
@@ -437,15 +403,15 @@ clutter_align_constraint_set_source (ClutterAlignConstraint *align,
G_CALLBACK (source_destroyed), G_CALLBACK (source_destroyed),
align); align);
g_signal_handlers_disconnect_by_func (old_source, g_signal_handlers_disconnect_by_func (old_source,
G_CALLBACK (source_queue_relayout), G_CALLBACK (source_position_changed),
align); align);
} }
align->source = source; align->source = source;
if (align->source != NULL) if (align->source != NULL)
{ {
g_signal_connect (align->source, "queue-relayout", g_signal_connect (align->source, "allocation-changed",
G_CALLBACK (source_queue_relayout), G_CALLBACK (source_position_changed),
align); align);
g_signal_connect (align->source, "destroy", g_signal_connect (align->source, "destroy",
G_CALLBACK (source_destroyed), G_CALLBACK (source_destroyed),
@@ -466,6 +432,8 @@ clutter_align_constraint_set_source (ClutterAlignConstraint *align,
* *
* Return value: (transfer none): the #ClutterActor used as the source * Return value: (transfer none): the #ClutterActor used as the source
* of the alignment * of the alignment
*
* Since: 1.4
*/ */
ClutterActor * ClutterActor *
clutter_align_constraint_get_source (ClutterAlignConstraint *align) clutter_align_constraint_get_source (ClutterAlignConstraint *align)
@@ -481,6 +449,8 @@ clutter_align_constraint_get_source (ClutterAlignConstraint *align)
* @axis: the axis to which the alignment refers to * @axis: the axis to which the alignment refers to
* *
* Sets the axis to which the alignment refers to * Sets the axis to which the alignment refers to
*
* Since: 1.4
*/ */
void void
clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align, clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align,
@@ -506,6 +476,8 @@ clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align,
* Retrieves the value set using clutter_align_constraint_set_align_axis() * Retrieves the value set using clutter_align_constraint_set_align_axis()
* *
* Return value: the alignment axis * Return value: the alignment axis
*
* Since: 1.4
*/ */
ClutterAlignAxis ClutterAlignAxis
clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align) clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align)
@@ -516,60 +488,6 @@ clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align)
return align->align_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
* clutter_align_constraint_set_pivot_point(). If no custom pivot
* point is set, -1 is set.
*/
void
clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align,
graphene_point_t *pivot_point)
{
g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
g_return_if_fail (pivot_point != NULL);
*pivot_point = align->pivot;
}
/** /**
* clutter_align_constraint_set_factor: * clutter_align_constraint_set_factor:
* @align: a #ClutterAlignConstraint * @align: a #ClutterAlignConstraint
@@ -586,6 +504,8 @@ clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align,
* meaning bottom, when #ClutterAlignConstraint:align-axis is set to * meaning bottom, when #ClutterAlignConstraint:align-axis is set to
* %CLUTTER_ALIGN_Y_AXIS). A value of 0.5 aligns in the middle in either * %CLUTTER_ALIGN_Y_AXIS). A value of 0.5 aligns in the middle in either
* cases * cases
*
* Since: 1.4
*/ */
void void
clutter_align_constraint_set_factor (ClutterAlignConstraint *align, clutter_align_constraint_set_factor (ClutterAlignConstraint *align,
@@ -608,6 +528,8 @@ clutter_align_constraint_set_factor (ClutterAlignConstraint *align,
* Retrieves the factor set using clutter_align_constraint_set_factor() * Retrieves the factor set using clutter_align_constraint_set_factor()
* *
* Return value: the alignment factor * Return value: the alignment factor
*
* Since: 1.4
*/ */
gfloat gfloat
clutter_align_constraint_get_factor (ClutterAlignConstraint *align) clutter_align_constraint_get_factor (ClutterAlignConstraint *align)

View File

@@ -37,6 +37,14 @@ G_BEGIN_DECLS
#define CLUTTER_ALIGN_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ALIGN_CONSTRAINT, ClutterAlignConstraint)) #define CLUTTER_ALIGN_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ALIGN_CONSTRAINT, ClutterAlignConstraint))
#define CLUTTER_IS_ALIGN_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ALIGN_CONSTRAINT)) #define CLUTTER_IS_ALIGN_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ALIGN_CONSTRAINT))
/**
* ClutterAlignConstraint:
*
* #ClutterAlignConstraint is an opaque structure
* whose members cannot be directly accesses
*
* Since: 1.4
*/
typedef struct _ClutterAlignConstraint ClutterAlignConstraint; typedef struct _ClutterAlignConstraint ClutterAlignConstraint;
typedef struct _ClutterAlignConstraintClass ClutterAlignConstraintClass; typedef struct _ClutterAlignConstraintClass ClutterAlignConstraintClass;
@@ -59,12 +67,6 @@ void clutter_align_constraint_set_align_axis (ClutterAlignConstrai
CLUTTER_EXPORT CLUTTER_EXPORT
ClutterAlignAxis clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align); ClutterAlignAxis clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align);
CLUTTER_EXPORT 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, void clutter_align_constraint_set_factor (ClutterAlignConstraint *align,
gfloat factor); gfloat factor);
CLUTTER_EXPORT CLUTTER_EXPORT

View File

@@ -23,26 +23,40 @@
*/ */
/** /**
* ClutterAnimatable: * SECTION:clutter-animatable
* @short_description: Interface for animatable classes
* *
* Interface for animatable classes * #ClutterAnimatable is an interface that allows a #GObject class
* * to control how a #ClutterAnimation will animate a property.
* #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 * Each #ClutterAnimatable should implement the
* [vfunc@Animatable.interpolate_value] virtual function of the * #ClutterAnimatableInterface.interpolate_property() virtual function of the
* interface to compute the animation state between two values of an interval * interface to compute the animation state between two values of an interval
* depending on a progress factor, expressed as a floating point value. * depending on a progress factor, expressed as a floating point value.
*
* If a #ClutterAnimatable is animated by a #ClutterAnimation
* instance, the #ClutterAnimation will call
* clutter_animatable_interpolate_property() passing the name of the
* currently animated property; the values interval; and the progress factor.
* The #ClutterAnimatable implementation should return the computed value for
* the animated
* property.
*
* #ClutterAnimatable is available since Clutter 1.0
*/ */
#include "clutter-build-config.h" #include "clutter-build-config.h"
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
#include "clutter-animatable.h" #include "clutter-animatable.h"
#include "clutter-interval.h" #include "clutter-interval.h"
#include "clutter-debug.h" #include "clutter-debug.h"
#include "clutter-private.h" #include "clutter-private.h"
#include "deprecated/clutter-animatable.h"
#include "deprecated/clutter-animation.h"
G_DEFINE_INTERFACE (ClutterAnimatable, clutter_animatable, G_TYPE_OBJECT); G_DEFINE_INTERFACE (ClutterAnimatable, clutter_animatable, G_TYPE_OBJECT);
static void static void
@@ -50,15 +64,91 @@ clutter_animatable_default_init (ClutterAnimatableInterface *iface)
{ {
} }
/**
* clutter_animatable_animate_property:
* @animatable: a #ClutterAnimatable
* @animation: a #ClutterAnimation
* @property_name: the name of the animated property
* @initial_value: the initial value of the animation interval
* @final_value: the final value of the animation interval
* @progress: the progress factor
* @value: return location for the animation value
*
* Calls the animate_property() virtual function for @animatable.
*
* The @initial_value and @final_value #GValue<!-- -->s must contain
* the same type; @value must have been initialized to the same
* type of @initial_value and @final_value.
*
* All implementation of the #ClutterAnimatable interface must
* implement this function.
*
* Return value: %TRUE if the value has been validated and can
* be applied to the #ClutterAnimatable, and %FALSE otherwise
*
* Since: 1.0
*
* Deprecated: 1.8: Use clutter_animatable_interpolate_value()
* instead
*/
gboolean
clutter_animatable_animate_property (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name,
const GValue *initial_value,
const GValue *final_value,
gdouble progress,
GValue *value)
{
ClutterAnimatableInterface *iface;
gboolean res;
g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), FALSE);
g_return_val_if_fail (CLUTTER_IS_ANIMATION (animation), FALSE);
g_return_val_if_fail (property_name != NULL, FALSE);
g_return_val_if_fail (initial_value != NULL && final_value != NULL, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (initial_value) != G_TYPE_INVALID, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (final_value) != G_TYPE_INVALID, FALSE);
g_return_val_if_fail (value != NULL, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (value) == G_VALUE_TYPE (initial_value) &&
G_VALUE_TYPE (value) == G_VALUE_TYPE (final_value),
FALSE);
iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable);
if (iface->animate_property == NULL)
{
ClutterInterval *interval;
interval = clutter_animation_get_interval (animation, property_name);
if (interval == NULL)
return FALSE;
res = clutter_animatable_interpolate_value (animatable, property_name,
interval,
progress,
value);
}
else
res = iface->animate_property (animatable, animation,
property_name,
initial_value, final_value,
progress,
value);
return res;
}
/** /**
* clutter_animatable_find_property: * clutter_animatable_find_property:
* @animatable: a #ClutterAnimatable * @animatable: a #ClutterAnimatable
* @property_name: the name of the animatable property to find * @property_name: the name of the animatable property to find
* *
* Finds the [class@GObject.ParamSpec] for @property_name * Finds the #GParamSpec for @property_name
* *
* Return value: (transfer none): The #GParamSpec for the given property * Return value: (transfer none): The #GParamSpec for the given property
* or %NULL * or %NULL
*
* Since: 1.4
*/ */
GParamSpec * GParamSpec *
clutter_animatable_find_property (ClutterAnimatable *animatable, clutter_animatable_find_property (ClutterAnimatable *animatable,
@@ -86,6 +176,8 @@ clutter_animatable_find_property (ClutterAnimatable *animatable,
* @value: a #GValue initialized to the type of the 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 * Retrieves the current state of @property_name and sets @value with it
*
* Since: 1.4
*/ */
void void
clutter_animatable_get_initial_state (ClutterAnimatable *animatable, clutter_animatable_get_initial_state (ClutterAnimatable *animatable,
@@ -113,6 +205,8 @@ clutter_animatable_get_initial_state (ClutterAnimatable *animatable,
* @value: the value of the animatable property to set * @value: the value of the animatable property to set
* *
* Sets the current state of @property_name to @value * Sets the current state of @property_name to @value
*
* Since: 1.4
*/ */
void void
clutter_animatable_set_final_state (ClutterAnimatable *animatable, clutter_animatable_set_final_state (ClutterAnimatable *animatable,
@@ -149,12 +243,14 @@ clutter_animatable_set_final_state (ClutterAnimatable *animatable,
* value, and store the result inside @value. * value, and store the result inside @value.
* *
* This function should be used for every property animation * This function should be used for every property animation
* involving `ClutterAnimatable`s. * involving #ClutterAnimatable<!-- -->s.
* *
* This function replaces clutter_animatable_animate_property(). * This function replaces clutter_animatable_animate_property().
* *
* Return value: %TRUE if the interpolation was successful, * Return value: %TRUE if the interpolation was successful,
* and %FALSE otherwise * and %FALSE otherwise
*
* Since: 1.8
*/ */
gboolean gboolean
clutter_animatable_interpolate_value (ClutterAnimatable *animatable, clutter_animatable_interpolate_value (ClutterAnimatable *animatable,
@@ -185,25 +281,3 @@ clutter_animatable_interpolate_value (ClutterAnimatable *animatable,
else else
return clutter_interval_compute_value (interval, progress, value); 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);
}

View File

@@ -42,6 +42,8 @@ G_DECLARE_INTERFACE (ClutterAnimatable, clutter_animatable,
/** /**
* ClutterAnimatableInterface: * ClutterAnimatableInterface:
* @animate_property: virtual function for custom interpolation of a
* property. This virtual function is deprecated
* @find_property: virtual function for retrieving the #GParamSpec of * @find_property: virtual function for retrieving the #GParamSpec of
* an animatable property * an animatable property
* @get_initial_state: virtual function for retrieving the initial * @get_initial_state: virtual function for retrieving the initial
@@ -50,7 +52,11 @@ G_DECLARE_INTERFACE (ClutterAnimatable, clutter_animatable,
* animatable property * animatable property
* @interpolate_value: virtual function for interpolating the progress * @interpolate_value: virtual function for interpolating the progress
* of a property * of a property
* @get_actor: virtual function for getting associated actor *
* Base interface for #GObject<!-- -->s that can be animated by a
* a #ClutterAnimation.
*
* Since: 1.0
*/ */
struct _ClutterAnimatableInterface struct _ClutterAnimatableInterface
{ {
@@ -58,6 +64,13 @@ struct _ClutterAnimatableInterface
GTypeInterface parent_iface; GTypeInterface parent_iface;
/*< public >*/ /*< public >*/
gboolean (* animate_property) (ClutterAnimatable *animatable,
ClutterAnimation *animation,
const gchar *property_name,
const GValue *initial_value,
const GValue *final_value,
gdouble progress,
GValue *value);
GParamSpec *(* find_property) (ClutterAnimatable *animatable, GParamSpec *(* find_property) (ClutterAnimatable *animatable,
const gchar *property_name); const gchar *property_name);
void (* get_initial_state) (ClutterAnimatable *animatable, void (* get_initial_state) (ClutterAnimatable *animatable,
@@ -71,7 +84,6 @@ struct _ClutterAnimatableInterface
ClutterInterval *interval, ClutterInterval *interval,
gdouble progress, gdouble progress,
GValue *value); GValue *value);
ClutterActor * (* get_actor) (ClutterAnimatable *animatable);
}; };
CLUTTER_EXPORT CLUTTER_EXPORT
@@ -92,9 +104,6 @@ gboolean clutter_animatable_interpolate_value (ClutterAnimatable *animatable,
gdouble progress, gdouble progress,
GValue *value); GValue *value);
CLUTTER_EXPORT
ClutterActor * clutter_animatable_get_actor (ClutterAnimatable *animatable);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_ANIMATABLE_H__ */ #endif /* __CLUTTER_ANIMATABLE_H__ */

View File

@@ -30,7 +30,9 @@
#ifndef __GI_SCANNER__ #ifndef __GI_SCANNER__
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActor, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActor, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorMeta, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAlignConstraint, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAlignConstraint, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackend, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackend, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBindConstraint, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBindConstraint, g_object_unref)
@@ -41,16 +43,21 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBoxLayout, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBrightnessContrastEffect, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBrightnessContrastEffect, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterCanvas, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterCanvas, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterChildMeta, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterChildMeta, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterClickAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterClone, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterClone, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColorizeEffect, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColorizeEffect, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterConstraint, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterConstraint, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterContainer, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterContainer, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDeformEffect, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDeformEffect, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDesaturateEffect, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDesaturateEffect, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDragAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDropAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterEffect, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterEffect, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFixedLayout, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFixedLayout, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFlowLayout, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFlowLayout, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterGestureAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterGridLayout, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterGridLayout, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterImage, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterInputDevice, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterInputDevice, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterInterval, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterInterval, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterKeyframeTransition, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterKeyframeTransition, g_object_unref)
@@ -82,10 +89,14 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterZoomAction, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorBox, clutter_actor_box_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorBox, clutter_actor_box_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColor, clutter_color_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColor, clutter_color_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMargin, clutter_margin_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMargin, clutter_margin_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintContext, clutter_paint_context_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMatrix, clutter_matrix_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintNode, clutter_paint_node_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintNode, clutter_paint_node_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintVolume, clutter_paint_volume_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintVolume, clutter_paint_volume_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPathNode, clutter_path_node_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPathNode, clutter_path_node_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPoint, clutter_point_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterRect, clutter_rect_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterSize, clutter_size_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterVertex, clutter_vertex_free)
#endif /* __GI_SCANNER__ */ #endif /* __GI_SCANNER__ */

View File

@@ -23,7 +23,8 @@
#define __CLUTTER_BACKEND_PRIVATE_H__ #define __CLUTTER_BACKEND_PRIVATE_H__
#include <clutter/clutter-backend.h> #include <clutter/clutter-backend.h>
#include <clutter/clutter-seat.h> #include <clutter/clutter-device-manager.h>
#include <clutter/clutter-keymap.h>
#include <clutter/clutter-stage-window.h> #include <clutter/clutter-stage-window.h>
#define CLUTTER_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BACKEND, ClutterBackendClass)) #define CLUTTER_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BACKEND, ClutterBackendClass))
@@ -46,6 +47,8 @@ struct _ClutterBackend
CoglOnscreen *dummy_onscreen; CoglOnscreen *dummy_onscreen;
ClutterDeviceManager *device_manager;
cairo_font_options_t *font_options; cairo_font_options_t *font_options;
gchar *font_name; gchar *font_name;
@@ -53,11 +56,11 @@ struct _ClutterBackend
gfloat units_per_em; gfloat units_per_em;
gint32 units_serial; gint32 units_serial;
float fallback_resource_scale;
ClutterStageWindow *stage_window; ClutterStageWindow *stage_window;
ClutterInputMethod *input_method; ClutterInputMethod *input_method;
ClutterKeymap *keymap;
}; };
struct _ClutterBackendClass struct _ClutterBackendClass
@@ -66,11 +69,18 @@ struct _ClutterBackendClass
GObjectClass parent_class; GObjectClass parent_class;
/* vfuncs */ /* vfuncs */
gboolean (* finish_init) (ClutterBackend *backend, gboolean (* pre_parse) (ClutterBackend *backend,
GError **error);
gboolean (* post_parse) (ClutterBackend *backend,
GError **error); GError **error);
ClutterStageWindow * (* create_stage) (ClutterBackend *backend, ClutterStageWindow * (* create_stage) (ClutterBackend *backend,
ClutterStage *wrapper, ClutterStage *wrapper,
GError **error); GError **error);
void (* init_events) (ClutterBackend *backend);
void (* init_features) (ClutterBackend *backend);
void (* add_options) (ClutterBackend *backend,
GOptionGroup *group);
ClutterFeatureFlags (* get_features) (ClutterBackend *backend);
CoglRenderer * (* get_renderer) (ClutterBackend *backend, CoglRenderer * (* get_renderer) (ClutterBackend *backend,
GError **error); GError **error);
CoglDisplay * (* get_display) (ClutterBackend *backend, CoglDisplay * (* get_display) (ClutterBackend *backend,
@@ -79,14 +89,17 @@ struct _ClutterBackendClass
GError **error); GError **error);
gboolean (* create_context) (ClutterBackend *backend, gboolean (* create_context) (ClutterBackend *backend,
GError **error); GError **error);
ClutterDeviceManager *(* get_device_manager) (ClutterBackend *backend);
gboolean (* translate_event) (ClutterBackend *backend, gboolean (* translate_event) (ClutterBackend *backend,
gpointer native, gpointer native,
ClutterEvent *event); ClutterEvent *event);
ClutterSeat * (* get_default_seat) (ClutterBackend *backend); PangoDirection (* get_keymap_direction) (ClutterBackend *backend);
gboolean (* is_display_server) (ClutterBackend *backend); void (* bell_notify) (ClutterBackend *backend);
ClutterKeymap * (* get_keymap) (ClutterBackend *backend);
/* signals */ /* signals */
void (* resolution_changed) (ClutterBackend *backend); void (* resolution_changed) (ClutterBackend *backend);
@@ -94,40 +107,48 @@ struct _ClutterBackendClass
void (* settings_changed) (ClutterBackend *backend); void (* settings_changed) (ClutterBackend *backend);
}; };
ClutterBackend * _clutter_create_backend (void);
ClutterStageWindow * _clutter_backend_create_stage (ClutterBackend *backend, ClutterStageWindow * _clutter_backend_create_stage (ClutterBackend *backend,
ClutterStage *wrapper, ClutterStage *wrapper,
GError **error); GError **error);
gboolean _clutter_backend_create_context (ClutterBackend *backend, gboolean _clutter_backend_create_context (ClutterBackend *backend,
GError **error); GError **error);
gboolean _clutter_backend_finish_init (ClutterBackend *backend, void _clutter_backend_add_options (ClutterBackend *backend,
GOptionGroup *group);
gboolean _clutter_backend_pre_parse (ClutterBackend *backend,
GError **error);
gboolean _clutter_backend_post_parse (ClutterBackend *backend,
GError **error); GError **error);
void _clutter_backend_init_events (ClutterBackend *backend);
void _clutter_backend_copy_event_data (ClutterBackend *backend,
const ClutterEvent *src,
ClutterEvent *dest);
void _clutter_backend_free_event_data (ClutterBackend *backend,
ClutterEvent *event);
CLUTTER_EXPORT CLUTTER_EXPORT
gboolean _clutter_backend_translate_event (ClutterBackend *backend, gboolean _clutter_backend_translate_event (ClutterBackend *backend,
gpointer native, gpointer native,
ClutterEvent *event); ClutterEvent *event);
ClutterFeatureFlags _clutter_backend_get_features (ClutterBackend *backend);
gfloat _clutter_backend_get_units_per_em (ClutterBackend *backend, gfloat _clutter_backend_get_units_per_em (ClutterBackend *backend,
PangoFontDescription *font_desc); PangoFontDescription *font_desc);
gint32 _clutter_backend_get_units_serial (ClutterBackend *backend); gint32 _clutter_backend_get_units_serial (ClutterBackend *backend);
PangoDirection _clutter_backend_get_keymap_direction (ClutterBackend *backend);
CLUTTER_EXPORT
void _clutter_backend_reset_cogl_framebuffer (ClutterBackend *backend);
void clutter_set_allowed_drivers (const char *drivers); void clutter_set_allowed_drivers (const char *drivers);
CLUTTER_EXPORT CLUTTER_EXPORT
ClutterStageWindow * clutter_backend_get_stage_window (ClutterBackend *backend); 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 G_END_DECLS
#endif /* __CLUTTER_BACKEND_PRIVATE_H__ */ #endif /* __CLUTTER_BACKEND_PRIVATE_H__ */

View File

@@ -25,9 +25,8 @@
*/ */
/** /**
* ClutterBackend: * SECTION:clutter-backend
* * @short_description: Backend abstraction
* Backend abstraction
* *
* Clutter can be compiled against different backends. Each backend * Clutter can be compiled against different backends. Each backend
* has to implement a set of functions, in order to be used by Clutter. * has to implement a set of functions, in order to be used by Clutter.
@@ -35,10 +34,14 @@
* #ClutterBackend is the base class abstracting the various implementation; * #ClutterBackend is the base class abstracting the various implementation;
* it provides a basic API to query the backend for generic information * it provides a basic API to query the backend for generic information
* and settings. * and settings.
*
* #ClutterBackend is available since Clutter 0.4
*/ */
#include "clutter-build-config.h" #include "clutter-build-config.h"
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-backend-private.h" #include "clutter-backend-private.h"
#include "clutter-debug.h" #include "clutter-debug.h"
#include "clutter-event-private.h" #include "clutter-event-private.h"
@@ -48,9 +51,27 @@
#include "clutter-stage-manager-private.h" #include "clutter-stage-manager-private.h"
#include "clutter-stage-private.h" #include "clutter-stage-private.h"
#include "clutter-stage-window.h" #include "clutter-stage-window.h"
#include "clutter-device-manager-private.h"
#ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
#include "wayland/clutter-wayland-compositor.h"
#endif
#include <cogl/cogl.h> #include <cogl/cogl.h>
#ifdef CLUTTER_INPUT_X11
#include "x11/clutter-backend-x11.h"
#endif
#ifdef CLUTTER_WINDOWING_EGL
#include "egl/clutter-backend-eglnative.h"
#endif
#ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
#include <cogl/cogl-wayland-server.h>
#include <wayland-server.h>
#include "wayland/clutter-wayland-compositor.h"
#endif
#define DEFAULT_FONT_NAME "Sans 10" #define DEFAULT_FONT_NAME "Sans 10"
enum enum
@@ -66,6 +87,12 @@ G_DEFINE_ABSTRACT_TYPE (ClutterBackend, clutter_backend, G_TYPE_OBJECT)
static guint backend_signals[LAST_SIGNAL] = { 0, }; static guint backend_signals[LAST_SIGNAL] = { 0, };
/* Global for being able to specify a compositor side wayland display
* pointer before clutter initialization */
#ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
static struct wl_display *_wayland_compositor_display;
#endif
static void static void
clutter_backend_dispose (GObject *gobject) clutter_backend_dispose (GObject *gobject)
{ {
@@ -74,20 +101,28 @@ clutter_backend_dispose (GObject *gobject)
/* clear the events still in the queue of the main context */ /* clear the events still in the queue of the main context */
_clutter_clear_events_queue (); _clutter_clear_events_queue ();
g_clear_object (&backend->dummy_onscreen); g_clear_pointer (&backend->dummy_onscreen, cogl_object_unref);
if (backend->stage_window) if (backend->stage_window)
{ {
g_object_remove_weak_pointer (G_OBJECT (backend->stage_window), g_object_remove_weak_pointer (G_OBJECT (backend->stage_window),
(gpointer *) &backend->stage_window); (gpointer *) &backend->stage_window);
backend->stage_window = NULL;
} }
g_clear_pointer (&backend->cogl_source, g_source_destroy); G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject);
g_clear_pointer (&backend->font_name, g_free); }
g_clear_pointer (&backend->font_options, cairo_font_options_destroy);
static void
clutter_backend_finalize (GObject *gobject)
{
ClutterBackend *backend = CLUTTER_BACKEND (gobject);
g_source_destroy (backend->cogl_source);
g_free (backend->font_name);
clutter_backend_set_font_options (backend, NULL);
g_clear_object (&backend->input_method); g_clear_object (&backend->input_method);
G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject); G_OBJECT_CLASS (clutter_backend_parent_class)->finalize (gobject);
} }
static gfloat static gfloat
@@ -188,20 +223,22 @@ clutter_backend_do_real_create_context (ClutterBackend *backend,
{ {
ClutterBackendClass *klass; ClutterBackendClass *klass;
CoglSwapChain *swap_chain; CoglSwapChain *swap_chain;
GError *internal_error;
klass = CLUTTER_BACKEND_GET_CLASS (backend); klass = CLUTTER_BACKEND_GET_CLASS (backend);
swap_chain = NULL; swap_chain = NULL;
internal_error = NULL;
CLUTTER_NOTE (BACKEND, "Creating Cogl renderer"); CLUTTER_NOTE (BACKEND, "Creating Cogl renderer");
backend->cogl_renderer = klass->get_renderer (backend, error); backend->cogl_renderer = klass->get_renderer (backend, &internal_error);
if (backend->cogl_renderer == NULL) if (backend->cogl_renderer == NULL)
goto error; goto error;
CLUTTER_NOTE (BACKEND, "Connecting the renderer"); CLUTTER_NOTE (BACKEND, "Connecting the renderer");
cogl_renderer_set_driver (backend->cogl_renderer, driver_id); cogl_renderer_set_driver (backend->cogl_renderer, driver_id);
if (!cogl_renderer_connect (backend->cogl_renderer, error)) if (!cogl_renderer_connect (backend->cogl_renderer, &internal_error))
goto error; goto error;
CLUTTER_NOTE (BACKEND, "Creating Cogl swap chain"); CLUTTER_NOTE (BACKEND, "Creating Cogl swap chain");
@@ -213,7 +250,7 @@ clutter_backend_do_real_create_context (ClutterBackend *backend,
backend->cogl_display = klass->get_display (backend, backend->cogl_display = klass->get_display (backend,
backend->cogl_renderer, backend->cogl_renderer,
swap_chain, swap_chain,
error); &internal_error);
} }
else else
{ {
@@ -229,7 +266,7 @@ clutter_backend_do_real_create_context (ClutterBackend *backend,
*/ */
res = cogl_renderer_check_onscreen_template (backend->cogl_renderer, res = cogl_renderer_check_onscreen_template (backend->cogl_renderer,
tmpl, tmpl,
error); &internal_error);
if (!res) if (!res)
goto error; goto error;
@@ -243,12 +280,17 @@ clutter_backend_do_real_create_context (ClutterBackend *backend,
if (backend->cogl_display == NULL) if (backend->cogl_display == NULL)
goto error; goto error;
#ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
cogl_wayland_display_set_compositor_display (backend->cogl_display,
_wayland_compositor_display);
#endif
CLUTTER_NOTE (BACKEND, "Setting up the display"); CLUTTER_NOTE (BACKEND, "Setting up the display");
if (!cogl_display_setup (backend->cogl_display, error)) if (!cogl_display_setup (backend->cogl_display, &internal_error))
goto error; goto error;
CLUTTER_NOTE (BACKEND, "Creating the Cogl context"); CLUTTER_NOTE (BACKEND, "Creating the Cogl context");
backend->cogl_context = cogl_context_new (backend->cogl_display, error); backend->cogl_context = cogl_context_new (backend->cogl_display, &internal_error);
if (backend->cogl_context == NULL) if (backend->cogl_context == NULL)
goto error; goto error;
@@ -352,7 +394,8 @@ clutter_backend_real_create_context (ClutterBackend *backend,
if (internal_error != NULL) if (internal_error != NULL)
g_propagate_error (error, internal_error); g_propagate_error (error, internal_error);
else else
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, g_set_error_literal (error, CLUTTER_INIT_ERROR,
CLUTTER_INIT_ERROR_BACKEND,
"Unable to initialize the Clutter backend: no available drivers found."); "Unable to initialize the Clutter backend: no available drivers found.");
return FALSE; return FALSE;
@@ -364,19 +407,167 @@ clutter_backend_real_create_context (ClutterBackend *backend,
return TRUE; return TRUE;
} }
static ClutterFeatureFlags
clutter_backend_real_get_features (ClutterBackend *backend)
{
ClutterFeatureFlags flags = 0;
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN))
{
CLUTTER_NOTE (BACKEND, "Cogl supports multiple onscreen framebuffers");
flags |= CLUTTER_FEATURE_STAGE_MULTIPLE;
}
else
{
CLUTTER_NOTE (BACKEND, "Cogl only supports one onscreen framebuffer");
flags |= CLUTTER_FEATURE_STAGE_STATIC;
}
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_THROTTLE))
{
CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers throttling");
flags |= CLUTTER_FEATURE_SWAP_THROTTLE;
}
else
CLUTTER_NOTE (BACKEND, "Cogl doesn't support swap buffers throttling");
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT))
{
CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers complete events");
flags |= CLUTTER_FEATURE_SWAP_EVENTS;
}
return flags;
}
static const char *allowed_backends;
static ClutterBackend * (* custom_backend_func) (void);
static const struct {
const char *name;
ClutterBackend * (* create_backend) (void);
} available_backends[] = {
#ifdef CLUTTER_WINDOWING_X11
{ CLUTTER_WINDOWING_X11, clutter_backend_x11_new },
#endif
#ifdef CLUTTER_WINDOWING_EGL
{ CLUTTER_WINDOWING_EGL, clutter_backend_egl_native_new },
#endif
{ NULL, NULL },
};
void
clutter_set_custom_backend_func (ClutterBackend *(* func) (void))
{
custom_backend_func = func;
}
ClutterBackend *
_clutter_create_backend (void)
{
const char *backends_list;
ClutterBackend *retval;
gboolean allow_any;
char **backends;
int i;
if (custom_backend_func)
{
retval = custom_backend_func ();
if (!retval)
g_error ("Failed to create custom backend.");
return retval;
}
if (allowed_backends == NULL)
allowed_backends = "*";
allow_any = strstr (allowed_backends, "*") != NULL;
backends_list = g_getenv ("CLUTTER_BACKEND");
if (backends_list == NULL)
backends_list = allowed_backends;
backends = g_strsplit (backends_list, ",", 0);
retval = NULL;
for (i = 0; retval == NULL && backends[i] != NULL; i++)
{
const char *backend = backends[i];
gboolean is_any = g_str_equal (backend, "*");
int j;
for (j = 0; available_backends[j].name != NULL; j++)
{
if ((is_any && allow_any) ||
(is_any && strstr (allowed_backends, available_backends[j].name)) ||
g_str_equal (backend, available_backends[j].name))
{
retval = available_backends[j].create_backend ();
if (retval != NULL)
break;
}
}
}
g_strfreev (backends);
if (retval == NULL)
g_error ("No default Clutter backend found.");
return retval;
}
static void
clutter_backend_real_init_events (ClutterBackend *backend)
{
g_error ("Unknown input backend");
}
static ClutterDeviceManager *
clutter_backend_real_get_device_manager (ClutterBackend *backend)
{
if (G_UNLIKELY (backend->device_manager == NULL))
{
g_critical ("No device manager available, expect broken input");
return NULL;
}
return backend->device_manager;
}
static ClutterKeymap *
clutter_backend_real_get_keymap (ClutterBackend *backend)
{
if (G_UNLIKELY (backend->keymap == NULL))
{
g_critical ("No keymap available, expect broken keyboard input");
return NULL;
}
return backend->keymap;
}
static void static void
clutter_backend_class_init (ClutterBackendClass *klass) clutter_backend_class_init (ClutterBackendClass *klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = clutter_backend_dispose; gobject_class->dispose = clutter_backend_dispose;
gobject_class->finalize = clutter_backend_finalize;
/** /**
* ClutterBackend::resolution-changed: * ClutterBackend::resolution-changed:
* @backend: the #ClutterBackend that emitted the signal * @backend: the #ClutterBackend that emitted the signal
* *
* The signal is emitted each time the font * The ::resolution-changed signal is emitted each time the font
* resolutions has been changed through #ClutterSettings. * resolutions has been changed through #ClutterSettings.
*
* Since: 1.0
*/ */
backend_signals[RESOLUTION_CHANGED] = backend_signals[RESOLUTION_CHANGED] =
g_signal_new (I_("resolution-changed"), g_signal_new (I_("resolution-changed"),
@@ -390,8 +581,10 @@ clutter_backend_class_init (ClutterBackendClass *klass)
* ClutterBackend::font-changed: * ClutterBackend::font-changed:
* @backend: the #ClutterBackend that emitted the signal * @backend: the #ClutterBackend that emitted the signal
* *
* The signal is emitted each time the font options * The ::font-changed signal is emitted each time the font options
* have been changed through #ClutterSettings. * have been changed through #ClutterSettings.
*
* Since: 1.0
*/ */
backend_signals[FONT_CHANGED] = backend_signals[FONT_CHANGED] =
g_signal_new (I_("font-changed"), g_signal_new (I_("font-changed"),
@@ -405,8 +598,10 @@ clutter_backend_class_init (ClutterBackendClass *klass)
* ClutterBackend::settings-changed: * ClutterBackend::settings-changed:
* @backend: the #ClutterBackend that emitted the signal * @backend: the #ClutterBackend that emitted the signal
* *
* The signal is emitted each time the #ClutterSettings * The ::settings-changed signal is emitted each time the #ClutterSettings
* properties have been changed. * properties have been changed.
*
* Since: 1.4
*/ */
backend_signals[SETTINGS_CHANGED] = backend_signals[SETTINGS_CHANGED] =
g_signal_new (I_("settings-changed"), g_signal_new (I_("settings-changed"),
@@ -419,7 +614,11 @@ clutter_backend_class_init (ClutterBackendClass *klass)
klass->resolution_changed = clutter_backend_real_resolution_changed; klass->resolution_changed = clutter_backend_real_resolution_changed;
klass->font_changed = clutter_backend_real_font_changed; klass->font_changed = clutter_backend_real_font_changed;
klass->init_events = clutter_backend_real_init_events;
klass->get_device_manager = clutter_backend_real_get_device_manager;
klass->create_context = clutter_backend_real_create_context; klass->create_context = clutter_backend_real_create_context;
klass->get_features = clutter_backend_real_get_features;
klass->get_keymap = clutter_backend_real_get_keymap;
} }
static void static void
@@ -428,13 +627,24 @@ clutter_backend_init (ClutterBackend *self)
self->units_per_em = -1.0; self->units_per_em = -1.0;
self->units_serial = 1; self->units_serial = 1;
self->dummy_onscreen = NULL; self->dummy_onscreen = COGL_INVALID_HANDLE;
}
self->fallback_resource_scale = 1.f; void
_clutter_backend_add_options (ClutterBackend *backend,
GOptionGroup *group)
{
ClutterBackendClass *klass;
g_assert (CLUTTER_IS_BACKEND (backend));
klass = CLUTTER_BACKEND_GET_CLASS (backend);
if (klass->add_options)
klass->add_options (backend, group);
} }
gboolean gboolean
_clutter_backend_finish_init (ClutterBackend *backend, _clutter_backend_pre_parse (ClutterBackend *backend,
GError **error) GError **error)
{ {
ClutterBackendClass *klass; ClutterBackendClass *klass;
@@ -442,8 +652,23 @@ _clutter_backend_finish_init (ClutterBackend *backend,
g_assert (CLUTTER_IS_BACKEND (backend)); g_assert (CLUTTER_IS_BACKEND (backend));
klass = CLUTTER_BACKEND_GET_CLASS (backend); klass = CLUTTER_BACKEND_GET_CLASS (backend);
if (klass->finish_init) if (klass->pre_parse)
return klass->finish_init (backend, error); return klass->pre_parse (backend, error);
return TRUE;
}
gboolean
_clutter_backend_post_parse (ClutterBackend *backend,
GError **error)
{
ClutterBackendClass *klass;
g_assert (CLUTTER_IS_BACKEND (backend));
klass = CLUTTER_BACKEND_GET_CLASS (backend);
if (klass->post_parse)
return klass->post_parse (backend, error);
return TRUE; return TRUE;
} }
@@ -488,6 +713,57 @@ _clutter_backend_create_context (ClutterBackend *backend,
return klass->create_context (backend, error); return klass->create_context (backend, error);
} }
ClutterFeatureFlags
_clutter_backend_get_features (ClutterBackend *backend)
{
ClutterBackendClass *klass;
GError *error;
g_assert (CLUTTER_IS_BACKEND (backend));
klass = CLUTTER_BACKEND_GET_CLASS (backend);
/* we need to have a context here; so we create the
* GL context first and the ask for features. if the
* context already exists this should be a no-op
*/
error = NULL;
if (klass->create_context != NULL)
{
gboolean res;
res = klass->create_context (backend, &error);
if (!res)
{
if (error)
{
g_critical ("Unable to create a context: %s", error->message);
g_error_free (error);
}
else
g_critical ("Unable to create a context: unknown error");
return 0;
}
}
if (klass->get_features)
return klass->get_features (backend);
return 0;
}
void
_clutter_backend_init_events (ClutterBackend *backend)
{
ClutterBackendClass *klass;
g_assert (CLUTTER_IS_BACKEND (backend));
klass = CLUTTER_BACKEND_GET_CLASS (backend);
klass->init_events (backend);
}
gfloat gfloat
_clutter_backend_get_units_per_em (ClutterBackend *backend, _clutter_backend_get_units_per_em (ClutterBackend *backend,
PangoFontDescription *font_desc) PangoFontDescription *font_desc)
@@ -502,6 +778,31 @@ _clutter_backend_get_units_per_em (ClutterBackend *backend,
return backend->units_per_em; return backend->units_per_em;
} }
void
_clutter_backend_copy_event_data (ClutterBackend *backend,
const ClutterEvent *src,
ClutterEvent *dest)
{
ClutterDeviceManagerClass *device_manager_class;
ClutterDeviceManager *device_manager;
device_manager = clutter_device_manager_get_default ();
device_manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
device_manager_class->copy_event_data (device_manager, src, dest);
}
void
_clutter_backend_free_event_data (ClutterBackend *backend,
ClutterEvent *event)
{
ClutterDeviceManagerClass *device_manager_class;
ClutterDeviceManager *device_manager;
device_manager = clutter_device_manager_get_default ();
device_manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
device_manager_class->free_event_data (device_manager, event);
}
/** /**
* clutter_get_default_backend: * clutter_get_default_backend:
* *
@@ -511,6 +812,8 @@ _clutter_backend_get_units_per_em (ClutterBackend *backend,
* Return value: (transfer none): the default backend. You should * Return value: (transfer none): the default backend. You should
* not ref or unref the returned object. Applications should rarely * not ref or unref the returned object. Applications should rarely
* need to use this. * need to use this.
*
* Since: 0.4
*/ */
ClutterBackend * ClutterBackend *
clutter_get_default_backend (void) clutter_get_default_backend (void)
@@ -539,6 +842,8 @@ clutter_get_default_backend (void)
* *
* Return value: the current resolution, or -1 if no resolution * Return value: the current resolution, or -1 if no resolution
* has been set. * has been set.
*
* Since: 0.4
*/ */
gdouble gdouble
clutter_backend_get_resolution (ClutterBackend *backend) clutter_backend_get_resolution (ClutterBackend *backend)
@@ -571,6 +876,8 @@ clutter_backend_get_resolution (ClutterBackend *backend)
* *
* This function is intended for actors creating a Pango layout * This function is intended for actors creating a Pango layout
* using the PangoCairo API. * using the PangoCairo API.
*
* Since: 0.8
*/ */
void void
clutter_backend_set_font_options (ClutterBackend *backend, clutter_backend_set_font_options (ClutterBackend *backend,
@@ -601,6 +908,8 @@ clutter_backend_set_font_options (ClutterBackend *backend,
* Return value: (transfer none): the font options of the #ClutterBackend. * Return value: (transfer none): the font options of the #ClutterBackend.
* The returned #cairo_font_options_t is owned by the backend and should * The returned #cairo_font_options_t is owned by the backend and should
* not be modified or freed * not be modified or freed
*
* Since: 0.8
*/ */
const cairo_font_options_t * const cairo_font_options_t *
clutter_backend_get_font_options (ClutterBackend *backend) clutter_backend_get_font_options (ClutterBackend *backend)
@@ -638,7 +947,7 @@ _clutter_backend_translate_event (ClutterBackend *backend,
} }
/** /**
* clutter_backend_get_cogl_context: * clutter_backend_get_cogl_context: (skip)
* @backend: a #ClutterBackend * @backend: a #ClutterBackend
* *
* Retrieves the #CoglContext associated with the given clutter * Retrieves the #CoglContext associated with the given clutter
@@ -653,6 +962,8 @@ _clutter_backend_translate_event (ClutterBackend *backend,
* explicitly create a CoglContext. * explicitly create a CoglContext.
* *
* Return value: (transfer none): The #CoglContext associated with @backend. * Return value: (transfer none): The #CoglContext associated with @backend.
*
* Since: 1.8
* Stability: unstable * Stability: unstable
*/ */
CoglContext * CoglContext *
@@ -661,6 +972,64 @@ clutter_backend_get_cogl_context (ClutterBackend *backend)
return backend->cogl_context; return backend->cogl_context;
} }
#ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
/**
* clutter_wayland_set_compositor_display:
* @display: A compositor side struct wl_display pointer
*
* This informs Clutter of your compositor side Wayland display
* object. This must be called before calling clutter_init().
*
* Since: 1.8
* Stability: unstable
*/
void
clutter_wayland_set_compositor_display (void *display)
{
if (_clutter_context_is_initialized ())
{
g_warning ("%s() can only be used before calling clutter_init()",
G_STRFUNC);
return;
}
_wayland_compositor_display = display;
}
#endif
PangoDirection
_clutter_backend_get_keymap_direction (ClutterBackend *backend)
{
ClutterBackendClass *klass;
klass = CLUTTER_BACKEND_GET_CLASS (backend);
if (klass->get_keymap_direction != NULL)
return klass->get_keymap_direction (backend);
return PANGO_DIRECTION_NEUTRAL;
}
void
_clutter_backend_reset_cogl_framebuffer (ClutterBackend *backend)
{
if (backend->dummy_onscreen == COGL_INVALID_HANDLE)
{
GError *internal_error = NULL;
backend->dummy_onscreen = cogl_onscreen_new (backend->cogl_context, 1, 1);
if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (backend->dummy_onscreen),
&internal_error))
{
g_critical ("Unable to create dummy onscreen: %s", internal_error->message);
g_error_free (internal_error);
return;
}
}
cogl_set_framebuffer (COGL_FRAMEBUFFER (backend->dummy_onscreen));
}
void void
clutter_set_allowed_drivers (const char *drivers) clutter_set_allowed_drivers (const char *drivers)
{ {
@@ -673,6 +1042,16 @@ clutter_set_allowed_drivers (const char *drivers)
allowed_drivers = g_strdup (drivers); allowed_drivers = g_strdup (drivers);
} }
void
clutter_backend_bell_notify (ClutterBackend *backend)
{
ClutterBackendClass *klass;
klass = CLUTTER_BACKEND_GET_CLASS (backend);
if (klass->bell_notify)
klass->bell_notify (backend);
}
/** /**
* clutter_backend_get_input_method: * clutter_backend_get_input_method:
* @backend: the #CLutterBackend * @backend: the #CLutterBackend
@@ -701,50 +1080,22 @@ clutter_backend_set_input_method (ClutterBackend *backend,
g_set_object (&backend->input_method, method); g_set_object (&backend->input_method, method);
} }
/**
* clutter_backend_get_keymap:
* @backend: the #ClutterBackend
*
* Gets the keymap used by Clutter
*
* Returns: (transfer none): the keymap
**/
ClutterKeymap *
clutter_backend_get_keymap (ClutterBackend *backend)
{
return CLUTTER_BACKEND_GET_CLASS (backend)->get_keymap (backend);
}
ClutterStageWindow * ClutterStageWindow *
clutter_backend_get_stage_window (ClutterBackend *backend) clutter_backend_get_stage_window (ClutterBackend *backend)
{ {
return backend->stage_window; 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);
}

View File

@@ -33,9 +33,9 @@
#include <cogl/cogl.h> #include <cogl/cogl.h>
#include <clutter/clutter-config.h>
#include <clutter/clutter-keymap.h> #include <clutter/clutter-keymap.h>
#include <clutter/clutter-types.h> #include <clutter/clutter-types.h>
#include <clutter/clutter-seat.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@@ -43,6 +43,14 @@ G_BEGIN_DECLS
#define CLUTTER_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BACKEND, ClutterBackend)) #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)) #define CLUTTER_IS_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BACKEND))
/**
* ClutterBackend:
*
* #ClutterBackend is an opaque structure whose
* members cannot be directly accessed.
*
* Since: 0.4
*/
typedef struct _ClutterBackend ClutterBackend; typedef struct _ClutterBackend ClutterBackend;
typedef struct _ClutterBackendClass ClutterBackendClass; typedef struct _ClutterBackendClass ClutterBackendClass;
@@ -64,6 +72,9 @@ const cairo_font_options_t * clutter_backend_get_font_options (Clutter
CLUTTER_EXPORT CLUTTER_EXPORT
CoglContext * clutter_backend_get_cogl_context (ClutterBackend *backend); CoglContext * clutter_backend_get_cogl_context (ClutterBackend *backend);
CLUTTER_EXPORT
void clutter_backend_bell_notify (ClutterBackend *backend);
CLUTTER_EXPORT CLUTTER_EXPORT
ClutterInputMethod * clutter_backend_get_input_method (ClutterBackend *backend); ClutterInputMethod * clutter_backend_get_input_method (ClutterBackend *backend);
@@ -71,7 +82,7 @@ CLUTTER_EXPORT
void clutter_backend_set_input_method (ClutterBackend *backend, void clutter_backend_set_input_method (ClutterBackend *backend,
ClutterInputMethod *method); ClutterInputMethod *method);
CLUTTER_EXPORT CLUTTER_EXPORT
ClutterSeat * clutter_backend_get_default_seat (ClutterBackend *backend); ClutterKeymap * clutter_backend_get_keymap (ClutterBackend *backend);
G_END_DECLS G_END_DECLS

File diff suppressed because it is too large Load Diff

View File

@@ -35,7 +35,7 @@
#undef CBZ_L2T_INTERPOLATION #undef CBZ_L2T_INTERPOLATION
/**************************************************************************** /****************************************************************************
* ClutterBezier -- representation of a cubic bezier curve * * ClutterBezier -- represenation of a cubic bezier curve *
* (private; a building block for the public bspline object) * * (private; a building block for the public bspline object) *
****************************************************************************/ ****************************************************************************/
@@ -104,7 +104,7 @@ struct _ClutterBezier
ClutterBezier * ClutterBezier *
_clutter_bezier_new (void) _clutter_bezier_new (void)
{ {
return g_new0 (ClutterBezier, 1); return g_slice_new0 (ClutterBezier);
} }
void void
@@ -112,7 +112,7 @@ _clutter_bezier_free (ClutterBezier * b)
{ {
if (G_LIKELY (b)) if (G_LIKELY (b))
{ {
g_free (b); g_slice_free (ClutterBezier, b);
} }
} }
@@ -213,7 +213,7 @@ sqrti (int number)
* algorithm does not calculate the square root, but its reciprocal ('y' * algorithm does not calculate the square root, but its reciprocal ('y'
* below), which is only at the end turned to the inverse value. In order * below), which is only at the end turned to the inverse value. In order
* for the algorithm to produce satisfactory results, the reciprocal value * for the algorithm to produce satisfactory results, the reciprocal value
* must be represented with sufficient precision; the 16.16 we use * must be represented with sufficient precission; the 16.16 we use
* elsewhere in clutter is not good enough, and 10.22 is used instead. * elsewhere in clutter is not good enough, and 10.22 is used instead.
*/ */
_FixedT x; _FixedT x;
@@ -236,7 +236,7 @@ sqrti (int number)
/* Now, we convert the float to 10.22 fixed. We exploit the mechanism /* Now, we convert the float to 10.22 fixed. We exploit the mechanism
* described at http://www.d6.com/users/checker/pdfs/gdmfp.pdf. * described at http://www.d6.com/users/checker/pdfs/gdmfp.pdf.
* *
* We want 22 bit fraction; a single precision float uses 23 bit * We want 22 bit fraction; a single precission float uses 23 bit
* mantisa, so we only need to add 2^(23-22) (no need for the 1.5 * mantisa, so we only need to add 2^(23-22) (no need for the 1.5
* multiplier as we are only dealing with positive numbers). * multiplier as we are only dealing with positive numbers).
* *
@@ -256,7 +256,7 @@ sqrti (int number)
flt2.i = (flt2.i >> 11) * (y_1 >> 11); flt2.i = (flt2.i >> 11) * (y_1 >> 11);
/* If the original argument is less than 342, we do another /* If the original argument is less than 342, we do another
* iteration to improve precision (for arguments >= 342, the single * iteration to improve precission (for arguments >= 342, the single
* iteration produces generally better results). * iteration produces generally better results).
*/ */
if (x < 171) if (x < 171)

View File

@@ -23,9 +23,8 @@
*/ */
/** /**
* ClutterBinLayout: * SECTION:clutter-bin-layout
* * @short_description: A simple layout manager
* A simple layout manager
* *
* #ClutterBinLayout is a layout manager which implements the following * #ClutterBinLayout is a layout manager which implements the following
* policy: * policy:
@@ -40,6 +39,8 @@
* *
* The [bin-layout example](https://git.gnome.org/browse/clutter/tree/examples/bin-layout.c?h=clutter-1.18) * The [bin-layout example](https://git.gnome.org/browse/clutter/tree/examples/bin-layout.c?h=clutter-1.18)
* shows how to pack actors inside a #ClutterBinLayout. * shows how to pack actors inside a #ClutterBinLayout.
*
* #ClutterBinLayout is available since Clutter 1.2
*/ */
#include "clutter-build-config.h" #include "clutter-build-config.h"
@@ -48,10 +49,10 @@
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS #define CLUTTER_DISABLE_DEPRECATION_WARNINGS
#include "deprecated/clutter-container.h" #include "deprecated/clutter-container.h"
#include "deprecated/clutter-bin-layout.h"
#include "clutter-actor-private.h" #include "clutter-actor-private.h"
#include "clutter-animatable.h" #include "clutter-animatable.h"
#include "clutter-bin-layout.h"
#include "clutter-child-meta.h" #include "clutter-child-meta.h"
#include "clutter-debug.h" #include "clutter-debug.h"
#include "clutter-enum-types.h" #include "clutter-enum-types.h"
@@ -405,7 +406,8 @@ get_actor_align_factor (ClutterActorAlign alignment)
static void static void
clutter_bin_layout_allocate (ClutterLayoutManager *manager, clutter_bin_layout_allocate (ClutterLayoutManager *manager,
ClutterContainer *container, ClutterContainer *container,
const ClutterActorBox *allocation) const ClutterActorBox *allocation,
ClutterAllocationFlags flags)
{ {
gfloat allocation_x, allocation_y; gfloat allocation_x, allocation_y;
gfloat available_w, available_h; gfloat available_w, available_h;
@@ -513,7 +515,8 @@ clutter_bin_layout_allocate (ClutterLayoutManager *manager,
clutter_actor_allocate_align_fill (child, &child_alloc, clutter_actor_allocate_align_fill (child, &child_alloc,
x_align, y_align, x_align, y_align,
x_fill, y_fill); x_fill, y_fill,
flags);
} }
} }
@@ -618,6 +621,8 @@ clutter_bin_layout_class_init (ClutterBinLayoutClass *klass)
* The default horizontal alignment policy for actors managed * The default horizontal alignment policy for actors managed
* by the #ClutterBinLayout * by the #ClutterBinLayout
* *
* Since: 1.2
*
* Deprecated: 1.12: Use the #ClutterActor:x-expand and the * Deprecated: 1.12: Use the #ClutterActor:x-expand and the
* #ClutterActor:x-align properties on #ClutterActor instead. * #ClutterActor:x-align properties on #ClutterActor instead.
*/ */
@@ -636,6 +641,8 @@ clutter_bin_layout_class_init (ClutterBinLayoutClass *klass)
* The default vertical alignment policy for actors managed * The default vertical alignment policy for actors managed
* by the #ClutterBinLayout * by the #ClutterBinLayout
* *
* Since: 1.2
*
* Deprecated: 1.12: Use the #ClutterActor:y-expand and the * Deprecated: 1.12: Use the #ClutterActor:y-expand and the
* #ClutterActor:y-align properties on #ClutterActor instead. * #ClutterActor:y-align properties on #ClutterActor instead.
*/ */
@@ -679,6 +686,8 @@ clutter_bin_layout_init (ClutterBinLayout *self)
* Creates a new #ClutterBinLayout layout manager * Creates a new #ClutterBinLayout layout manager
* *
* Return value: the newly created layout manager * Return value: the newly created layout manager
*
* Since: 1.2
*/ */
ClutterLayoutManager * ClutterLayoutManager *
clutter_bin_layout_new (ClutterBinAlignment x_align, clutter_bin_layout_new (ClutterBinAlignment x_align,
@@ -689,3 +698,187 @@ clutter_bin_layout_new (ClutterBinAlignment x_align,
"y-align", y_align, "y-align", y_align,
NULL); NULL);
} }
/**
* clutter_bin_layout_set_alignment:
* @self: a #ClutterBinLayout
* @child: (allow-none): a child of @container
* @x_align: the horizontal alignment policy to be used for the @child
* inside @container
* @y_align: the vertical aligment policy to be used on the @child
* inside @container
*
* Sets the horizontal and vertical alignment policies to be applied
* to a @child of @self
*
* If @child is %NULL then the @x_align and @y_align values will
* be set as the default alignment policies
*
* Since: 1.2
*
* Deprecated: 1.12: Use the #ClutterActor:x-align and
* #ClutterActor:y-align properties of #ClutterActor instead.
*/
void
clutter_bin_layout_set_alignment (ClutterBinLayout *self,
ClutterActor *child,
ClutterBinAlignment x_align,
ClutterBinAlignment y_align)
{
ClutterBinLayoutPrivate *priv;
ClutterLayoutManager *manager;
ClutterLayoutMeta *meta;
g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self));
g_return_if_fail (child == NULL || CLUTTER_IS_ACTOR (child));
priv = self->priv;
if (priv->container == NULL)
{
if (child == NULL)
{
set_x_align (self, x_align);
set_y_align (self, y_align);
}
else
g_warning ("The layout of type '%s' must be associated to "
"a ClutterContainer before setting the alignment "
"on its children",
G_OBJECT_TYPE_NAME (self));
return;
}
manager = CLUTTER_LAYOUT_MANAGER (self);
meta = clutter_layout_manager_get_child_meta (manager,
priv->container,
child);
g_assert (CLUTTER_IS_BIN_LAYER (meta));
set_layer_x_align (CLUTTER_BIN_LAYER (meta), x_align);
set_layer_y_align (CLUTTER_BIN_LAYER (meta), y_align);
}
/**
* clutter_bin_layout_get_alignment:
* @self: a #ClutterBinLayout
* @child: (allow-none): a child of @container
* @x_align: (out) (allow-none): return location for the horizontal
* alignment policy
* @y_align: (out) (allow-none): return location for the vertical
* alignment policy
*
* Retrieves the horizontal and vertical alignment policies for
* a child of @self
*
* If @child is %NULL the default alignment policies will be returned
* instead
*
* Since: 1.2
*
* Deprecated: 1.12: Use the #ClutterActor:x-align and the
* #ClutterActor:y-align properties of #ClutterActor instead.
*/
void
clutter_bin_layout_get_alignment (ClutterBinLayout *self,
ClutterActor *child,
ClutterBinAlignment *x_align,
ClutterBinAlignment *y_align)
{
ClutterBinLayoutPrivate *priv;
ClutterLayoutManager *manager;
ClutterLayoutMeta *meta;
ClutterBinLayer *layer;
g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self));
priv = self->priv;
if (priv->container == NULL)
{
if (child == NULL)
{
if (x_align)
*x_align = priv->x_align;
if (y_align)
*y_align = priv->y_align;
}
else
g_warning ("The layout of type '%s' must be associated to "
"a ClutterContainer before getting the alignment "
"of its children",
G_OBJECT_TYPE_NAME (self));
return;
}
manager = CLUTTER_LAYOUT_MANAGER (self);
meta = clutter_layout_manager_get_child_meta (manager,
priv->container,
child);
g_assert (CLUTTER_IS_BIN_LAYER (meta));
layer = CLUTTER_BIN_LAYER (meta);
if (x_align)
*x_align = layer->x_align;
if (y_align)
*y_align = layer->y_align;
}
/**
* clutter_bin_layout_add:
* @self: a #ClutterBinLayout
* @child: a #ClutterActor
* @x_align: horizontal alignment policy for @child
* @y_align: vertical alignment policy for @child
*
* Adds a #ClutterActor to the container using @self and
* sets the alignment policies for it
*
* This function is equivalent to clutter_container_add_actor()
* and clutter_layout_manager_child_set_property() but it does not
* require a pointer to the #ClutterContainer associated to the
* #ClutterBinLayout
*
* Since: 1.2
*
* Deprecated: 1.12: Use clutter_actor_add_child() instead.
*/
void
clutter_bin_layout_add (ClutterBinLayout *self,
ClutterActor *child,
ClutterBinAlignment x_align,
ClutterBinAlignment y_align)
{
ClutterBinLayoutPrivate *priv;
ClutterLayoutManager *manager;
ClutterLayoutMeta *meta;
g_return_if_fail (CLUTTER_IS_BIN_LAYOUT (self));
g_return_if_fail (CLUTTER_IS_ACTOR (child));
priv = self->priv;
if (priv->container == NULL)
{
g_warning ("The layout of type '%s' must be associated to "
"a ClutterContainer before adding children",
G_OBJECT_TYPE_NAME (self));
return;
}
clutter_container_add_actor (priv->container, child);
manager = CLUTTER_LAYOUT_MANAGER (self);
meta = clutter_layout_manager_get_child_meta (manager,
priv->container,
child);
g_assert (CLUTTER_IS_BIN_LAYER (meta));
set_layer_x_align (CLUTTER_BIN_LAYER (meta), x_align);
set_layer_y_align (CLUTTER_BIN_LAYER (meta), y_align);
}

View File

@@ -44,6 +44,14 @@ typedef struct _ClutterBinLayout ClutterBinLayout;
typedef struct _ClutterBinLayoutPrivate ClutterBinLayoutPrivate; typedef struct _ClutterBinLayoutPrivate ClutterBinLayoutPrivate;
typedef struct _ClutterBinLayoutClass ClutterBinLayoutClass; typedef struct _ClutterBinLayoutClass ClutterBinLayoutClass;
/**
* ClutterBinLayout:
*
* The #ClutterBinLayout structure contains only private data
* and should be accessed using the provided API
*
* Since: 1.2
*/
struct _ClutterBinLayout struct _ClutterBinLayout
{ {
/*< private >*/ /*< private >*/
@@ -57,6 +65,8 @@ struct _ClutterBinLayout
* *
* The #ClutterBinLayoutClass structure contains only private * The #ClutterBinLayoutClass structure contains only private
* data and should be accessed using the provided API * data and should be accessed using the provided API
*
* Since: 1.2
*/ */
struct _ClutterBinLayoutClass struct _ClutterBinLayoutClass
{ {

View File

@@ -23,29 +23,27 @@
*/ */
/** /**
* ClutterBindConstraint: * SECTION:clutter-bind-constraint
* @Title: ClutterBindConstraint
* @Short_Description: A constraint binding the position or size of an actor
* *
* A constraint binding the position or size of an actor * #ClutterBindConstraint is a #ClutterConstraint that binds the
* * position or the size of the #ClutterActor to which it is applied
* #ClutterBindConstraint is a [class@Constraint] that binds the * to the the position or the size of another #ClutterActor, or
* 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". * "source".
* *
* An offset can be applied to the constraint, to avoid overlapping. The offset * 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 * can also be animated. For instance, the following code will set up three
* actors to be bound to the same origin: * actors to be bound to the same origin:
* *
* ```c * |[<!-- language="C" -->
* // source * // source
* rect[0] = clutter_actor_new (); * rect[0] = clutter_rectangle_new_with_color (&red_color);
* clutter_actor_set_background_color (rect[0], &red_color);
* clutter_actor_set_position (rect[0], x_pos, y_pos); * clutter_actor_set_position (rect[0], x_pos, y_pos);
* clutter_actor_set_size (rect[0], 100, 100); * clutter_actor_set_size (rect[0], 100, 100);
* *
* // second rectangle * // second rectangle
* rect[1] = clutter_actor_new (); * rect[1] = clutter_rectangle_new_with_color (&green_color);
* clutter_actor_set_background_color (rect[1], &green_color);
* clutter_actor_set_size (rect[1], 100, 100); * clutter_actor_set_size (rect[1], 100, 100);
* clutter_actor_set_opacity (rect[1], 0); * clutter_actor_set_opacity (rect[1], 0);
* *
@@ -55,8 +53,7 @@
* clutter_actor_add_constraint_with_name (rect[1], "green-y", constraint); * clutter_actor_add_constraint_with_name (rect[1], "green-y", constraint);
* *
* // third rectangle * // third rectangle
* rect[2] = clutter_actor_new (); * rect[2] = clutter_rectangle_new_with_color (&blue_color);
* clutter_actor_set_background_color (rect[2], &blue_color);
* clutter_actor_set_size (rect[2], 100, 100); * clutter_actor_set_size (rect[2], 100, 100);
* clutter_actor_set_opacity (rect[2], 0); * clutter_actor_set_opacity (rect[2], 0);
* *
@@ -64,12 +61,12 @@
* clutter_actor_add_constraint_with_name (rect[2], "blue-x", constraint); * clutter_actor_add_constraint_with_name (rect[2], "blue-x", constraint);
* constraint = clutter_bind_constraint_new (rect[0], CLUTTER_BIND_Y, 0.0); * constraint = clutter_bind_constraint_new (rect[0], CLUTTER_BIND_Y, 0.0);
* clutter_actor_add_constraint_with_name (rect[2], "blue-y", constraint); * clutter_actor_add_constraint_with_name (rect[2], "blue-y", constraint);
* ``` * ]|
* *
* The following code animates the second and third rectangles to "expand" * The following code animates the second and third rectangles to "expand"
* them horizontally from underneath the first rectangle: * them horizontally from underneath the first rectangle:
* *
* ```c * |[<!-- language="C" -->
* clutter_actor_animate (rect[1], CLUTTER_EASE_OUT_CUBIC, 250, * clutter_actor_animate (rect[1], CLUTTER_EASE_OUT_CUBIC, 250,
* "@constraints.green-x.offset", 100.0, * "@constraints.green-x.offset", 100.0,
* "opacity", 255, * "opacity", 255,
@@ -78,7 +75,9 @@
* "@constraints.blue-x.offset", 200.0, * "@constraints.blue-x.offset", 200.0,
* "opacity", 255, * "opacity", 255,
* NULL); * NULL);
* ``` * ]|
*
* #ClutterBindConstraint is available since Clutter 1.4
*/ */
#include "clutter-build-config.h" #include "clutter-build-config.h"
@@ -145,58 +144,6 @@ source_destroyed (ClutterActor *actor,
bind->source = NULL; 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 static void
clutter_bind_constraint_update_allocation (ClutterConstraint *constraint, clutter_bind_constraint_update_allocation (ClutterConstraint *constraint,
ClutterActor *actor, ClutterActor *actor,
@@ -205,9 +152,7 @@ clutter_bind_constraint_update_allocation (ClutterConstraint *constraint,
ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint); ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint);
gfloat source_width, source_height; gfloat source_width, source_height;
gfloat actor_width, actor_height; gfloat actor_width, actor_height;
graphene_point3d_t source_position; ClutterVertex source_position = { 0., };
source_position = GRAPHENE_POINT3D_INIT (0.f, 0.f, 0.f);
if (bind->source == NULL) if (bind->source == NULL)
return; return;
@@ -381,8 +326,6 @@ clutter_bind_constraint_class_init (ClutterBindConstraintClass *klass)
meta_class->set_actor = clutter_bind_constraint_set_actor; meta_class->set_actor = clutter_bind_constraint_set_actor;
constraint_class->update_allocation = clutter_bind_constraint_update_allocation; constraint_class->update_allocation = clutter_bind_constraint_update_allocation;
constraint_class->update_preferred_size = clutter_bind_constraint_update_preferred_size;
/** /**
* ClutterBindConstraint:source: * ClutterBindConstraint:source:
* *
@@ -390,6 +333,8 @@ clutter_bind_constraint_class_init (ClutterBindConstraintClass *klass)
* *
* The #ClutterActor must not be contained inside the actor associated * The #ClutterActor must not be contained inside the actor associated
* to the constraint. * to the constraint.
*
* Since: 1.4
*/ */
obj_props[PROP_SOURCE] = obj_props[PROP_SOURCE] =
g_param_spec_object ("source", g_param_spec_object ("source",
@@ -402,6 +347,8 @@ clutter_bind_constraint_class_init (ClutterBindConstraintClass *klass)
* ClutterBindConstraint:coordinate: * ClutterBindConstraint:coordinate:
* *
* The coordinate to be bound * The coordinate to be bound
*
* Since: 1.4
*/ */
obj_props[PROP_COORDINATE] = obj_props[PROP_COORDINATE] =
g_param_spec_enum ("coordinate", g_param_spec_enum ("coordinate",
@@ -415,6 +362,8 @@ clutter_bind_constraint_class_init (ClutterBindConstraintClass *klass)
* ClutterBindConstraint:offset: * ClutterBindConstraint:offset:
* *
* The offset, in pixels, to be applied to the binding * The offset, in pixels, to be applied to the binding
*
* Since: 1.4
*/ */
obj_props[PROP_OFFSET] = obj_props[PROP_OFFSET] =
g_param_spec_float ("offset", g_param_spec_float ("offset",
@@ -449,6 +398,8 @@ clutter_bind_constraint_init (ClutterBindConstraint *self)
* the given @coordinate of the position of @source * the given @coordinate of the position of @source
* *
* Return value: the newly created #ClutterBindConstraint * Return value: the newly created #ClutterBindConstraint
*
* Since: 1.4
*/ */
ClutterConstraint * ClutterConstraint *
clutter_bind_constraint_new (ClutterActor *source, clutter_bind_constraint_new (ClutterActor *source,
@@ -470,6 +421,8 @@ clutter_bind_constraint_new (ClutterActor *source,
* @source: (allow-none): a #ClutterActor, or %NULL to unset the source * @source: (allow-none): a #ClutterActor, or %NULL to unset the source
* *
* Sets the source #ClutterActor for the constraint * Sets the source #ClutterActor for the constraint
*
* Since: 1.4
*/ */
void void
clutter_bind_constraint_set_source (ClutterBindConstraint *constraint, clutter_bind_constraint_set_source (ClutterBindConstraint *constraint,
@@ -535,6 +488,8 @@ clutter_bind_constraint_set_source (ClutterBindConstraint *constraint,
* Retrieves the #ClutterActor set using clutter_bind_constraint_set_source() * Retrieves the #ClutterActor set using clutter_bind_constraint_set_source()
* *
* Return value: (transfer none): a pointer to the source actor * Return value: (transfer none): a pointer to the source actor
*
* Since: 1.4
*/ */
ClutterActor * ClutterActor *
clutter_bind_constraint_get_source (ClutterBindConstraint *constraint) clutter_bind_constraint_get_source (ClutterBindConstraint *constraint)
@@ -550,6 +505,8 @@ clutter_bind_constraint_get_source (ClutterBindConstraint *constraint)
* @coordinate: the coordinate to bind * @coordinate: the coordinate to bind
* *
* Sets the coordinate to bind in the constraint * Sets the coordinate to bind in the constraint
*
* Since: 1.4
*/ */
void void
clutter_bind_constraint_set_coordinate (ClutterBindConstraint *constraint, clutter_bind_constraint_set_coordinate (ClutterBindConstraint *constraint,
@@ -575,6 +532,8 @@ clutter_bind_constraint_set_coordinate (ClutterBindConstraint *constraint,
* Retrieves the bound coordinate of the constraint * Retrieves the bound coordinate of the constraint
* *
* Return value: the bound coordinate * Return value: the bound coordinate
*
* Since: 1.4
*/ */
ClutterBindCoordinate ClutterBindCoordinate
clutter_bind_constraint_get_coordinate (ClutterBindConstraint *constraint) clutter_bind_constraint_get_coordinate (ClutterBindConstraint *constraint)
@@ -591,6 +550,8 @@ clutter_bind_constraint_get_coordinate (ClutterBindConstraint *constraint)
* @offset: the offset to apply, in pixels * @offset: the offset to apply, in pixels
* *
* Sets the offset to be applied to the constraint * Sets the offset to be applied to the constraint
*
* Since: 1.4
*/ */
void void
clutter_bind_constraint_set_offset (ClutterBindConstraint *constraint, clutter_bind_constraint_set_offset (ClutterBindConstraint *constraint,
@@ -616,6 +577,8 @@ clutter_bind_constraint_set_offset (ClutterBindConstraint *constraint,
* Retrieves the offset set using clutter_bind_constraint_set_offset() * Retrieves the offset set using clutter_bind_constraint_set_offset()
* *
* Return value: the offset, in pixels * Return value: the offset, in pixels
*
* Since: 1.4
*/ */
gfloat gfloat
clutter_bind_constraint_get_offset (ClutterBindConstraint *bind) clutter_bind_constraint_get_offset (ClutterBindConstraint *bind)

View File

@@ -37,6 +37,14 @@ G_BEGIN_DECLS
#define CLUTTER_BIND_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BIND_CONSTRAINT, ClutterBindConstraint)) #define CLUTTER_BIND_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BIND_CONSTRAINT, ClutterBindConstraint))
#define CLUTTER_IS_BIND_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BIND_CONSTRAINT)) #define CLUTTER_IS_BIND_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BIND_CONSTRAINT))
/**
* ClutterBindConstraint:
*
* #ClutterBindConstraint is an opaque structure
* whose members cannot be directly accessed
*
* Since: 1.4
*/
typedef struct _ClutterBindConstraint ClutterBindConstraint; typedef struct _ClutterBindConstraint ClutterBindConstraint;
typedef struct _ClutterBindConstraintClass ClutterBindConstraintClass; typedef struct _ClutterBindConstraintClass ClutterBindConstraintClass;

View File

@@ -22,9 +22,8 @@
*/ */
/** /**
* ClutterBindingPool * SECTION:clutter-binding-pool
* * @short_description: Pool for key bindings
* Pool for key bindings
* *
* #ClutterBindingPool is a data structure holding a set of key bindings. * #ClutterBindingPool is a data structure holding a set of key bindings.
* Each key binding associates a key symbol (eventually with modifiers) * Each key binding associates a key symbol (eventually with modifiers)
@@ -39,7 +38,7 @@
* inside their class initialization function and then install actions * inside their class initialization function and then install actions
* like this: * like this:
* *
* ```c * |[<!-- language="C" -->
* static void * static void
* foo_class_init (FooClass *klass) * foo_class_init (FooClass *klass)
* { * {
@@ -56,23 +55,23 @@
* G_CALLBACK (foo_action_move_up), * G_CALLBACK (foo_action_move_up),
* NULL, NULL); * NULL, NULL);
* } * }
* ``` * ]|
* *
* The callback has a signature of: * The callback has a signature of:
* *
* ```c * |[<!-- language="C" -->
* gboolean (* callback) (GObject *instance, * gboolean (* callback) (GObject *instance,
* const gchar *action_name, * const gchar *action_name,
* guint key_val, * guint key_val,
* ClutterModifierType modifiers, * ClutterModifierType modifiers,
* gpointer user_data); * gpointer user_data);
* ``` * ]|
* *
* The actor should then override the [signal@Actor::key-press-event] and * The actor should then override the #ClutterActor::key-press-event and
* use [method@BindingPool.activate] to match a [struct@KeyEvent] structure * use clutter_binding_pool_activate() to match a #ClutterKeyEvent structure
* to one of the actions: * to one of the actions:
* *
* ```c * |[<!-- language="C" -->
* ClutterBindingPool *pool; * ClutterBindingPool *pool;
* *
* // retrieve the binding pool for the type of the actor * // retrieve the binding pool for the type of the actor
@@ -85,12 +84,14 @@
* key_event->keyval, * key_event->keyval,
* key_event->modifier_state, * key_event->modifier_state,
* G_OBJECT (actor)); * G_OBJECT (actor));
* ``` * ]|
* *
* The [method@BindingPool.activate] function will return %FALSE if * The clutter_binding_pool_activate() function will return %FALSE if
* no action for the given key binding was found, if the action was * no action for the given key binding was found, if the action was
* blocked (using [method@BindingPool.block_action]) or if the * blocked (using clutter_binding_pool_block_action()) or if the
* key binding handler returned %FALSE. * key binding handler returned %FALSE.
*
* #ClutterBindingPool is available since Clutter 1.0
*/ */
#include "clutter-build-config.h" #include "clutter-build-config.h"
@@ -188,7 +189,7 @@ binding_entry_new (const gchar *name,
modifiers = modifiers & BINDING_MOD_MASK; modifiers = modifiers & BINDING_MOD_MASK;
entry = g_new0 (ClutterBindingEntry, 1); entry = g_slice_new (ClutterBindingEntry);
entry->key_val = key_val; entry->key_val = key_val;
entry->modifiers = modifiers; entry->modifiers = modifiers;
entry->name = (gchar *) g_intern_string (name); entry->name = (gchar *) g_intern_string (name);
@@ -220,7 +221,7 @@ binding_entry_free (gpointer data)
g_closure_unref (entry->closure); g_closure_unref (entry->closure);
g_free (entry); g_slice_free (ClutterBindingEntry, entry);
} }
} }
@@ -306,6 +307,8 @@ clutter_binding_pool_class_init (ClutterBindingPoolClass *klass)
* ClutterBindingPool:name: * ClutterBindingPool:name:
* *
* The unique name of the #ClutterBindingPool. * The unique name of the #ClutterBindingPool.
*
* Since: 1.0
*/ */
obj_props[PROP_NAME] = obj_props[PROP_NAME] =
g_param_spec_string ("name", g_param_spec_string ("name",
@@ -342,6 +345,8 @@ clutter_binding_pool_init (ClutterBindingPool *pool)
* *
* Return value: the newly created binding pool with the given * Return value: the newly created binding pool with the given
* name. Use g_object_unref() when done. * name. Use g_object_unref() when done.
*
* Since: 1.0
*/ */
ClutterBindingPool * ClutterBindingPool *
clutter_binding_pool_new (const gchar *name) clutter_binding_pool_new (const gchar *name)
@@ -377,13 +382,15 @@ clutter_binding_pool_new (const gchar *name)
* A binding pool for a class can also be retrieved using * A binding pool for a class can also be retrieved using
* clutter_binding_pool_find() with the class type name: * clutter_binding_pool_find() with the class type name:
* *
* ``` * |[
* pool = clutter_binding_pool_find (G_OBJECT_TYPE_NAME (instance)); * pool = clutter_binding_pool_find (G_OBJECT_TYPE_NAME (instance));
* ``` * ]|
* *
* Return value: (transfer none): the binding pool for the given class. * Return value: (transfer none): the binding pool for the given class.
* The returned #ClutterBindingPool is owned by Clutter and should not * The returned #ClutterBindingPool is owned by Clutter and should not
* be freed directly * be freed directly
*
* Since: 1.0
*/ */
ClutterBindingPool * ClutterBindingPool *
clutter_binding_pool_get_for_class (gpointer klass) clutter_binding_pool_get_for_class (gpointer klass)
@@ -414,6 +421,8 @@ clutter_binding_pool_get_for_class (gpointer klass)
* Finds the #ClutterBindingPool with @name. * Finds the #ClutterBindingPool with @name.
* *
* Return value: (transfer none): a pointer to the #ClutterBindingPool, or %NULL * Return value: (transfer none): a pointer to the #ClutterBindingPool, or %NULL
*
* Since: 1.0
*/ */
ClutterBindingPool * ClutterBindingPool *
clutter_binding_pool_find (const gchar *name) clutter_binding_pool_find (const gchar *name)
@@ -456,6 +465,8 @@ clutter_binding_pool_find (const gchar *name)
* *
* Actions can be blocked with clutter_binding_pool_block_action() * Actions can be blocked with clutter_binding_pool_block_action()
* and then unblocked using clutter_binding_pool_unblock_action(). * and then unblocked using clutter_binding_pool_unblock_action().
*
* Since: 1.0
*/ */
void void
clutter_binding_pool_install_action (ClutterBindingPool *pool, clutter_binding_pool_install_action (ClutterBindingPool *pool,
@@ -524,6 +535,8 @@ clutter_binding_pool_install_action (ClutterBindingPool *pool,
* *
* Actions can be blocked with clutter_binding_pool_block_action() * Actions can be blocked with clutter_binding_pool_block_action()
* and then unblocked using clutter_binding_pool_unblock_action(). * and then unblocked using clutter_binding_pool_unblock_action().
*
* Since: 1.0
*/ */
void void
clutter_binding_pool_install_closure (ClutterBindingPool *pool, clutter_binding_pool_install_closure (ClutterBindingPool *pool,
@@ -585,6 +598,8 @@ clutter_binding_pool_install_closure (ClutterBindingPool *pool,
* *
* Actions can be blocked with clutter_binding_pool_block_action() * Actions can be blocked with clutter_binding_pool_block_action()
* and then unblocked using clutter_binding_pool_unblock_action(). * and then unblocked using clutter_binding_pool_unblock_action().
*
* Since: 1.0
*/ */
void void
clutter_binding_pool_override_action (ClutterBindingPool *pool, clutter_binding_pool_override_action (ClutterBindingPool *pool,
@@ -647,6 +662,8 @@ clutter_binding_pool_override_action (ClutterBindingPool *pool,
* *
* Actions can be blocked with clutter_binding_pool_block_action() * Actions can be blocked with clutter_binding_pool_block_action()
* and then unblocked using clutter_binding_pool_unblock_action(). * and then unblocked using clutter_binding_pool_unblock_action().
*
* Since: 1.0
*/ */
void void
clutter_binding_pool_override_closure (ClutterBindingPool *pool, clutter_binding_pool_override_closure (ClutterBindingPool *pool,
@@ -700,6 +717,8 @@ clutter_binding_pool_override_closure (ClutterBindingPool *pool,
* Return value: the name of the action, if found, or %NULL. The * Return value: the name of the action, if found, or %NULL. The
* returned string is owned by the binding pool and should never * returned string is owned by the binding pool and should never
* be modified or freed * be modified or freed
*
* Since: 1.0
*/ */
const gchar * const gchar *
clutter_binding_pool_find_action (ClutterBindingPool *pool, clutter_binding_pool_find_action (ClutterBindingPool *pool,
@@ -726,6 +745,8 @@ clutter_binding_pool_find_action (ClutterBindingPool *pool,
* *
* Removes the action matching the given @key_val, @modifiers pair, * Removes the action matching the given @key_val, @modifiers pair,
* if any exists. * if any exists.
*
* Since: 1.0
*/ */
void void
clutter_binding_pool_remove_action (ClutterBindingPool *pool, clutter_binding_pool_remove_action (ClutterBindingPool *pool,
@@ -811,13 +832,13 @@ clutter_binding_entry_invoke (ClutterBindingEntry *entry,
* *
* The callback has the following signature: * The callback has the following signature:
* *
* ``` * |[
* void (* callback) (GObject *gobject, * void (* callback) (GObject *gobject,
* const gchar *action_name, * const gchar *action_name,
* guint key_val, * guint key_val,
* ClutterModifierType modifiers, * ClutterModifierType modifiers,
* gpointer user_data); * gpointer user_data);
* ``` * ]|
* *
* Where the #GObject instance is @gobject and the user data * Where the #GObject instance is @gobject and the user data
* is the one passed when installing the action with * is the one passed when installing the action with
@@ -828,6 +849,8 @@ clutter_binding_entry_invoke (ClutterBindingEntry *entry,
* will not be invoked, and this function will return %FALSE. * will not be invoked, and this function will return %FALSE.
* *
* Return value: %TRUE if an action was found and was activated * Return value: %TRUE if an action was found and was activated
*
* Since: 1.0
*/ */
gboolean gboolean
clutter_binding_pool_activate (ClutterBindingPool *pool, clutter_binding_pool_activate (ClutterBindingPool *pool,
@@ -859,6 +882,8 @@ clutter_binding_pool_activate (ClutterBindingPool *pool,
* @action_name: an action name * @action_name: an action name
* *
* Blocks all the actions with name @action_name inside @pool. * Blocks all the actions with name @action_name inside @pool.
*
* Since: 1.0
*/ */
void void
clutter_binding_pool_block_action (ClutterBindingPool *pool, clutter_binding_pool_block_action (ClutterBindingPool *pool,
@@ -888,6 +913,8 @@ clutter_binding_pool_block_action (ClutterBindingPool *pool,
* Unblocking an action does not cause the callback bound to it to * Unblocking an action does not cause the callback bound to it to
* be invoked in case clutter_binding_pool_activate() was called on * be invoked in case clutter_binding_pool_activate() was called on
* an action previously blocked with clutter_binding_pool_block_action(). * an action previously blocked with clutter_binding_pool_block_action().
*
* Since: 1.0
*/ */
void void
clutter_binding_pool_unblock_action (ClutterBindingPool *pool, clutter_binding_pool_unblock_action (ClutterBindingPool *pool,

View File

@@ -37,6 +37,14 @@ G_BEGIN_DECLS
#define CLUTTER_BINDING_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BINDING_POOL, ClutterBindingPool)) #define CLUTTER_BINDING_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BINDING_POOL, ClutterBindingPool))
#define CLUTTER_IS_BINDING_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BINDING_POOL)) #define CLUTTER_IS_BINDING_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BINDING_POOL))
/**
* ClutterBindingPool:
*
* Container of key bindings. The #ClutterBindingPool struct is
* private.
*
* Since: 1.0
*/
typedef struct _ClutterBindingPool ClutterBindingPool; typedef struct _ClutterBindingPool ClutterBindingPool;
typedef struct _ClutterBindingPoolClass ClutterBindingPoolClass; typedef struct _ClutterBindingPoolClass ClutterBindingPoolClass;
@@ -54,6 +62,8 @@ typedef struct _ClutterBindingPoolClass ClutterBindingPoolClass;
* *
* Return value: the function should return %TRUE if the key * Return value: the function should return %TRUE if the key
* binding has been handled, and return %FALSE otherwise * binding has been handled, and return %FALSE otherwise
*
* Since: 1.0
*/ */
typedef gboolean (* ClutterBindingActionFunc) (GObject *gobject, typedef gboolean (* ClutterBindingActionFunc) (GObject *gobject,
const gchar *action_name, const gchar *action_name,

View File

@@ -23,12 +23,14 @@
*/ */
/** /**
* ClutterBlurEffect: * SECTION:clutter-blur-effect
* * @short_description: A blur effect
* A blur effect * @see_also: #ClutterEffect, #ClutterOffscreenEffect
* *
* #ClutterBlurEffect is a sub-class of #ClutterEffect that allows blurring a * #ClutterBlurEffect is a sub-class of #ClutterEffect that allows blurring a
* actor and its contents. * actor and its contents.
*
* #ClutterBlurEffect is available since Clutter 1.4
*/ */
#define CLUTTER_BLUR_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BLUR_EFFECT, ClutterBlurEffectClass)) #define CLUTTER_BLUR_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BLUR_EFFECT, ClutterBlurEffectClass))
@@ -37,6 +39,8 @@
#include "clutter-build-config.h" #include "clutter-build-config.h"
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-blur-effect.h" #include "clutter-blur-effect.h"
#include "cogl/cogl.h" #include "cogl/cogl.h"
@@ -77,6 +81,9 @@ struct _ClutterBlurEffect
gint pixel_step_uniform; gint pixel_step_uniform;
gint tex_width;
gint tex_height;
CoglPipeline *pipeline; CoglPipeline *pipeline;
}; };
@@ -91,33 +98,83 @@ G_DEFINE_TYPE (ClutterBlurEffect,
clutter_blur_effect, clutter_blur_effect,
CLUTTER_TYPE_OFFSCREEN_EFFECT); CLUTTER_TYPE_OFFSCREEN_EFFECT);
static CoglPipeline * static gboolean
clutter_blur_effect_create_pipeline (ClutterOffscreenEffect *effect, clutter_blur_effect_pre_paint (ClutterEffect *effect)
CoglTexture *texture)
{ {
ClutterBlurEffect *blur_effect = CLUTTER_BLUR_EFFECT (effect); ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect);
ClutterEffectClass *parent_class;
if (blur_effect->pixel_step_uniform > -1) if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
return FALSE;
self->actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
if (self->actor == NULL)
return FALSE;
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
{ {
float pixel_step[2]; /* if we don't have support for GLSL shaders then we
int tex_width, tex_height; * forcibly disable the ActorMeta
*/
g_warning ("Unable to use the ShaderEffect: the graphics hardware "
"or the current GL driver does not implement support "
"for the GLSL shading language.");
clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE);
return FALSE;
}
tex_width = cogl_texture_get_width (texture); parent_class = CLUTTER_EFFECT_CLASS (clutter_blur_effect_parent_class);
tex_height = cogl_texture_get_height (texture); if (parent_class->pre_paint (effect))
{
ClutterOffscreenEffect *offscreen_effect =
CLUTTER_OFFSCREEN_EFFECT (effect);
CoglHandle texture;
pixel_step[0] = 1.0f / tex_width; texture = clutter_offscreen_effect_get_texture (offscreen_effect);
pixel_step[1] = 1.0f / tex_height; self->tex_width = cogl_texture_get_width (texture);
self->tex_height = cogl_texture_get_height (texture);
cogl_pipeline_set_uniform_float (blur_effect->pipeline, if (self->pixel_step_uniform > -1)
blur_effect->pixel_step_uniform, {
gfloat pixel_step[2];
pixel_step[0] = 1.0f / self->tex_width;
pixel_step[1] = 1.0f / self->tex_height;
cogl_pipeline_set_uniform_float (self->pipeline,
self->pixel_step_uniform,
2, /* n_components */ 2, /* n_components */
1, /* count */ 1, /* count */
pixel_step); pixel_step);
} }
cogl_pipeline_set_layer_texture (blur_effect->pipeline, 0, texture); cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
return cogl_object_ref (blur_effect->pipeline); return TRUE;
}
else
return FALSE;
}
static void
clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect)
{
ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect);
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
guint8 paint_opacity;
paint_opacity = clutter_actor_get_paint_opacity (self->actor);
cogl_pipeline_set_color4ub (self->pipeline,
paint_opacity,
paint_opacity,
paint_opacity,
paint_opacity);
cogl_framebuffer_draw_rectangle (framebuffer,
self->pipeline,
0, 0,
self->tex_width, self->tex_height);
} }
static gboolean static gboolean
@@ -125,7 +182,7 @@ clutter_blur_effect_modify_paint_volume (ClutterEffect *effect,
ClutterPaintVolume *volume) ClutterPaintVolume *volume)
{ {
gfloat cur_width, cur_height; gfloat cur_width, cur_height;
graphene_point3d_t origin; ClutterVertex origin;
clutter_paint_volume_get_origin (volume, &origin); clutter_paint_volume_get_origin (volume, &origin);
cur_width = clutter_paint_volume_get_width (volume); cur_width = clutter_paint_volume_get_width (volume);
@@ -165,10 +222,11 @@ clutter_blur_effect_class_init (ClutterBlurEffectClass *klass)
gobject_class->dispose = clutter_blur_effect_dispose; gobject_class->dispose = clutter_blur_effect_dispose;
effect_class->pre_paint = clutter_blur_effect_pre_paint;
effect_class->modify_paint_volume = clutter_blur_effect_modify_paint_volume; effect_class->modify_paint_volume = clutter_blur_effect_modify_paint_volume;
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
offscreen_class->create_pipeline = clutter_blur_effect_create_pipeline; offscreen_class->paint_target = clutter_blur_effect_paint_target;
} }
static void static void
@@ -207,6 +265,8 @@ clutter_blur_effect_init (ClutterBlurEffect *self)
* clutter_actor_add_effect() * clutter_actor_add_effect()
* *
* Return value: the newly created #ClutterBlurEffect or %NULL * Return value: the newly created #ClutterBlurEffect or %NULL
*
* Since: 1.4
*/ */
ClutterEffect * ClutterEffect *
clutter_blur_effect_new (void) clutter_blur_effect_new (void)

View File

@@ -37,6 +37,14 @@ G_BEGIN_DECLS
#define CLUTTER_BLUR_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BLUR_EFFECT, ClutterBlurEffect)) #define CLUTTER_BLUR_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BLUR_EFFECT, ClutterBlurEffect))
#define CLUTTER_IS_BLUR_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BLUR_EFFECT)) #define CLUTTER_IS_BLUR_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BLUR_EFFECT))
/**
* ClutterBlurEffect:
*
* #ClutterBlurEffect is an opaque structure
* whose members cannot be accessed directly
*
* Since: 1.4
*/
typedef struct _ClutterBlurEffect ClutterBlurEffect; typedef struct _ClutterBlurEffect ClutterBlurEffect;
typedef struct _ClutterBlurEffectClass ClutterBlurEffectClass; typedef struct _ClutterBlurEffectClass ClutterBlurEffectClass;

View File

@@ -1,40 +0,0 @@
/*
* Copyright (C) 2020 Endless OS Foundation, LLC
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CLUTTER_BLUR_PRIVATE_H
#define CLUTTER_BLUR_PRIVATE_H
#include <glib-object.h>
#include <cogl/cogl.h>
G_BEGIN_DECLS
typedef struct _ClutterBlur ClutterBlur;
ClutterBlur * clutter_blur_new (CoglTexture *texture,
float sigma);
void clutter_blur_apply (ClutterBlur *blur);
CoglTexture * clutter_blur_get_texture (ClutterBlur *blur);
void clutter_blur_free (ClutterBlur *blur);
G_END_DECLS
#endif /* CLUTTER_BLUR_PRIVATE_H */

View File

@@ -1,431 +0,0 @@
/*
* Copyright (C) 2020 Endless OS Foundation, LLC
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "clutter-blur-private.h"
#include "clutter-backend.h"
/**
* SECTION:clutter-blur
* @short_description: Blur textures
*
* #ClutterBlur is a moderately fast gaussian blur implementation.
*
* # Optimizations
*
* There are a number of optimizations in place to make this blur implementation
* real-time. All in all, the implementation performs best when using large
* blur-radii that allow downscaling the texture to smaller sizes, at small
* radii where no downscaling is possible this can easily halve the framerate.
*
* ## Multipass
*
* It is implemented in 2 passes: vertical and horizontal.
*
* ## Downscaling
*
* #ClutterBlur uses dynamic downscaling to speed up blurring. Downscaling
* happens in factors of 2 (the image is downscaled either by 2, 4, 8, 16, …)
* and depends on the blur radius, the texture size, among others.
*
* The texture is drawn into a downscaled framebuffer; the blur passes are
* applied on the downscaled texture contents; and finally, the blurred
* contents are drawn
* upscaled again.
*
* ## Hardware Interpolation
*
* This blur implementation cuts down the number of sampling operations by
* exploiting the hardware interpolation that is performed when sampling between
* pixel boundaries. This technique is described at:
*
* http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
*
* ## Incremental gauss-factor calculation
*
* The kernel values for the gaussian kernel are computed incrementally instead
* of running the expensive calculations multiple times inside the blur shader.
* The implementation is based on the algorithm presented by K. Turkowski in
* GPU Gems 3, chapter 40:
*
* https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch40.html
*
*/
static const char *gaussian_blur_glsl_declarations =
"uniform float sigma; \n"
"uniform float pixel_step; \n"
"uniform vec2 direction; \n";
static const char *gaussian_blur_glsl =
" vec2 uv = vec2 (cogl_tex_coord.st); \n"
" \n"
" vec3 gauss_coefficient; \n"
" gauss_coefficient.x = 1.0 / (sqrt (2.0 * 3.14159265) * sigma); \n"
" gauss_coefficient.y = exp (-0.5 / (sigma * sigma)); \n"
" gauss_coefficient.z = gauss_coefficient.y * gauss_coefficient.y; \n"
" \n"
" float gauss_coefficient_total = gauss_coefficient.x; \n"
" \n"
" vec4 ret = texture2D (cogl_sampler, uv) * gauss_coefficient.x; \n"
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
" \n"
" int n_steps = int (ceil (1.5 * sigma)) * 2; \n"
" \n"
" for (int i = 1; i <= n_steps; i += 2) { \n"
" float coefficient_subtotal = gauss_coefficient.x; \n"
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
" coefficient_subtotal += gauss_coefficient.x; \n"
" \n"
" float gauss_ratio = gauss_coefficient.x / coefficient_subtotal; \n"
" \n"
" float foffset = float (i) + gauss_ratio; \n"
" vec2 offset = direction * foffset * pixel_step; \n"
" \n"
" ret += texture2D (cogl_sampler, uv + offset) * coefficient_subtotal; \n"
" ret += texture2D (cogl_sampler, uv - offset) * coefficient_subtotal; \n"
" \n"
" gauss_coefficient_total += 2.0 * coefficient_subtotal; \n"
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
" } \n"
" \n"
" cogl_texel = ret / gauss_coefficient_total; \n";
#define MIN_DOWNSCALE_SIZE 256.f
#define MAX_SIGMA 6.f
enum
{
VERTICAL,
HORIZONTAL,
};
typedef struct
{
CoglFramebuffer *framebuffer;
CoglPipeline *pipeline;
CoglTexture *texture;
int orientation;
} BlurPass;
struct _ClutterBlur
{
CoglTexture *source_texture;
float sigma;
float downscale_factor;
BlurPass pass[2];
};
static CoglPipeline*
create_blur_pipeline (void)
{
static CoglPipelineKey blur_pipeline_key = "clutter-blur-pipeline-private";
CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ());
CoglPipeline *blur_pipeline;
blur_pipeline =
cogl_context_get_named_pipeline (ctx, &blur_pipeline_key);
if (G_UNLIKELY (blur_pipeline == NULL))
{
CoglSnippet *snippet;
blur_pipeline = cogl_pipeline_new (ctx);
cogl_pipeline_set_layer_null_texture (blur_pipeline, 0);
cogl_pipeline_set_layer_filters (blur_pipeline,
0,
COGL_PIPELINE_FILTER_LINEAR,
COGL_PIPELINE_FILTER_LINEAR);
cogl_pipeline_set_layer_wrap_mode (blur_pipeline,
0,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
gaussian_blur_glsl_declarations,
NULL);
cogl_snippet_set_replace (snippet, gaussian_blur_glsl);
cogl_pipeline_add_layer_snippet (blur_pipeline, 0, snippet);
cogl_object_unref (snippet);
cogl_context_set_named_pipeline (ctx, &blur_pipeline_key, blur_pipeline);
}
return cogl_pipeline_copy (blur_pipeline);
}
static void
update_blur_uniforms (ClutterBlur *blur,
BlurPass *pass)
{
gboolean vertical = pass->orientation == VERTICAL;
int sigma_uniform;
int pixel_step_uniform;
int direction_uniform;
pixel_step_uniform =
cogl_pipeline_get_uniform_location (pass->pipeline, "pixel_step");
if (pixel_step_uniform > -1)
{
float pixel_step;
if (vertical)
pixel_step = 1.f / cogl_texture_get_height (pass->texture);
else
pixel_step = 1.f / cogl_texture_get_width (pass->texture);
cogl_pipeline_set_uniform_1f (pass->pipeline,
pixel_step_uniform,
pixel_step);
}
sigma_uniform = cogl_pipeline_get_uniform_location (pass->pipeline, "sigma");
if (sigma_uniform > -1)
{
cogl_pipeline_set_uniform_1f (pass->pipeline,
sigma_uniform,
blur->sigma / blur->downscale_factor);
}
direction_uniform =
cogl_pipeline_get_uniform_location (pass->pipeline, "direction");
if (direction_uniform > -1)
{
gboolean horizontal = !vertical;
float direction[2] = {
horizontal,
vertical,
};
cogl_pipeline_set_uniform_float (pass->pipeline,
direction_uniform,
2, 1,
direction);
}
}
static gboolean
create_fbo (ClutterBlur *blur,
BlurPass *pass)
{
CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ());
float scaled_height;
float scaled_width;
float height;
float width;
g_clear_pointer (&pass->texture, cogl_object_unref);
g_clear_object (&pass->framebuffer);
width = cogl_texture_get_width (blur->source_texture);
height = cogl_texture_get_height (blur->source_texture);
scaled_width = floorf (width / blur->downscale_factor);
scaled_height = floorf (height / blur->downscale_factor);
pass->texture = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx,
scaled_width,
scaled_height));
if (!pass->texture)
return FALSE;
pass->framebuffer =
COGL_FRAMEBUFFER (cogl_offscreen_new_with_texture (pass->texture));
if (!pass->framebuffer)
{
g_warning ("%s: Unable to create an Offscreen buffer", G_STRLOC);
return FALSE;
}
cogl_framebuffer_orthographic (pass->framebuffer,
0.0, 0.0,
scaled_width,
scaled_height,
0.0, 1.0);
return TRUE;
}
static gboolean
setup_blur_pass (ClutterBlur *blur,
BlurPass *pass,
int orientation,
CoglTexture *texture)
{
pass->orientation = orientation;
pass->pipeline = create_blur_pipeline ();
cogl_pipeline_set_layer_texture (pass->pipeline, 0, texture);
if (!create_fbo (blur, pass))
return FALSE;
update_blur_uniforms (blur, pass);
return TRUE;
}
static float
calculate_downscale_factor (float width,
float height,
float sigma)
{
float downscale_factor = 1.f;
float scaled_width = width;
float scaled_height = height;
float scaled_sigma = sigma;
/* This is the algorithm used by Firefox; keep downscaling until either the
* blur radius is lower than the threshold, or the downscaled texture is too
* small.
*/
while (scaled_sigma > MAX_SIGMA &&
scaled_width > MIN_DOWNSCALE_SIZE &&
scaled_height > MIN_DOWNSCALE_SIZE)
{
downscale_factor *= 2.f;
scaled_width = width / downscale_factor;
scaled_height = height / downscale_factor;
scaled_sigma = sigma / downscale_factor;
}
return downscale_factor;
}
static void
apply_blur_pass (BlurPass *pass)
{
CoglColor transparent;
cogl_color_init_from_4ub (&transparent, 0, 0, 0, 0);
cogl_framebuffer_clear (pass->framebuffer,
COGL_BUFFER_BIT_COLOR,
&transparent);
cogl_framebuffer_draw_rectangle (pass->framebuffer,
pass->pipeline,
0, 0,
cogl_texture_get_width (pass->texture),
cogl_texture_get_height (pass->texture));
}
static void
clear_blur_pass (BlurPass *pass)
{
g_clear_pointer (&pass->pipeline, cogl_object_unref);
g_clear_pointer (&pass->texture, cogl_object_unref);
g_clear_object (&pass->framebuffer);
}
/**
* clutter_blur_new:
* @texture: a #CoglTexture
* @sigma: blur sigma
*
* Creates a new #ClutterBlur.
*
* Returns: (transfer full) (nullable): A newly created #ClutterBlur
*/
ClutterBlur *
clutter_blur_new (CoglTexture *texture,
float sigma)
{
ClutterBlur *blur;
unsigned int height;
unsigned int width;
BlurPass *hpass;
BlurPass *vpass;
g_return_val_if_fail (texture != NULL, NULL);
g_return_val_if_fail (sigma >= 0.0, NULL);
width = cogl_texture_get_width (texture);
height = cogl_texture_get_height (texture);
blur = g_new0 (ClutterBlur, 1);
blur->sigma = sigma;
blur->source_texture = cogl_object_ref (texture);
blur->downscale_factor = calculate_downscale_factor (width, height, sigma);
if (G_APPROX_VALUE (sigma, 0.0, FLT_EPSILON))
goto out;
vpass = &blur->pass[VERTICAL];
hpass = &blur->pass[HORIZONTAL];
if (!setup_blur_pass (blur, vpass, VERTICAL, texture) ||
!setup_blur_pass (blur, hpass, HORIZONTAL, vpass->texture))
{
clutter_blur_free (blur);
return NULL;
}
out:
return g_steal_pointer (&blur);
}
/**
* clutter_blur_apply:
* @blur: a #ClutterBlur
*
* Applies the blur. The resulting texture can be retrieved by
* clutter_blur_get_texture().
*/
void
clutter_blur_apply (ClutterBlur *blur)
{
if (G_APPROX_VALUE (blur->sigma, 0.0, FLT_EPSILON))
return;
apply_blur_pass (&blur->pass[VERTICAL]);
apply_blur_pass (&blur->pass[HORIZONTAL]);
}
/**
* clutter_blur_get_texture:
* @blur: a #ClutterBlur
*
* Retrieves the texture where the blurred contents are stored. The
* contents are undefined until clutter_blur_apply() is called.
*
* Returns: (transfer none): a #CoglTexture
*/
CoglTexture *
clutter_blur_get_texture (ClutterBlur *blur)
{
if (G_APPROX_VALUE (blur->sigma, 0.0, FLT_EPSILON))
return blur->source_texture;
else
return blur->pass[HORIZONTAL].texture;
}
/**
* clutter_blur_free:
* @blur: A #ClutterBlur
*
* Frees @blur.
*/
void
clutter_blur_free (ClutterBlur *blur)
{
g_assert (blur);
clear_blur_pass (&blur->pass[VERTICAL]);
clear_blur_pass (&blur->pass[HORIZONTAL]);
cogl_clear_object (&blur->source_texture);
g_free (blur);
}

File diff suppressed because it is too large Load Diff

View File

@@ -47,6 +47,14 @@ typedef struct _ClutterBoxLayout ClutterBoxLayout;
typedef struct _ClutterBoxLayoutPrivate ClutterBoxLayoutPrivate; typedef struct _ClutterBoxLayoutPrivate ClutterBoxLayoutPrivate;
typedef struct _ClutterBoxLayoutClass ClutterBoxLayoutClass; typedef struct _ClutterBoxLayoutClass ClutterBoxLayoutClass;
/**
* ClutterBoxLayout:
*
* The #ClutterBoxLayout structure contains only private data
* and should be accessed using the provided API
*
* Since: 1.2
*/
struct _ClutterBoxLayout struct _ClutterBoxLayout
{ {
/*< private >*/ /*< private >*/
@@ -60,6 +68,8 @@ struct _ClutterBoxLayout
* *
* The #ClutterBoxLayoutClass structure contains only private * The #ClutterBoxLayoutClass structure contains only private
* data and should be accessed using the provided API * data and should be accessed using the provided API
*
* Since: 1.2
*/ */
struct _ClutterBoxLayoutClass struct _ClutterBoxLayoutClass
{ {
@@ -89,6 +99,69 @@ void clutter_box_layout_set_homogeneous (ClutterBoxLayou
gboolean homogeneous); gboolean homogeneous);
CLUTTER_EXPORT CLUTTER_EXPORT
gboolean clutter_box_layout_get_homogeneous (ClutterBoxLayout *layout); gboolean clutter_box_layout_get_homogeneous (ClutterBoxLayout *layout);
CLUTTER_EXPORT
void clutter_box_layout_set_pack_start (ClutterBoxLayout *layout,
gboolean pack_start);
CLUTTER_EXPORT
gboolean clutter_box_layout_get_pack_start (ClutterBoxLayout *layout);
CLUTTER_DEPRECATED_FOR(clutter_box_layout_set_orientation)
void clutter_box_layout_set_vertical (ClutterBoxLayout *layout,
gboolean vertical);
CLUTTER_DEPRECATED_FOR(clutter_box_layout_get_orientation)
gboolean clutter_box_layout_get_vertical (ClutterBoxLayout *layout);
CLUTTER_EXPORT
void clutter_box_layout_pack (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean expand,
gboolean x_fill,
gboolean y_fill,
ClutterBoxAlignment x_align,
ClutterBoxAlignment y_align);
CLUTTER_DEPRECATED
void clutter_box_layout_set_alignment (ClutterBoxLayout *layout,
ClutterActor *actor,
ClutterBoxAlignment x_align,
ClutterBoxAlignment y_align);
CLUTTER_DEPRECATED
void clutter_box_layout_get_alignment (ClutterBoxLayout *layout,
ClutterActor *actor,
ClutterBoxAlignment *x_align,
ClutterBoxAlignment *y_align);
CLUTTER_DEPRECATED
void clutter_box_layout_set_fill (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean x_fill,
gboolean y_fill);
CLUTTER_DEPRECATED
void clutter_box_layout_get_fill (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean *x_fill,
gboolean *y_fill);
CLUTTER_DEPRECATED
void clutter_box_layout_set_expand (ClutterBoxLayout *layout,
ClutterActor *actor,
gboolean expand);
CLUTTER_DEPRECATED
gboolean clutter_box_layout_get_expand (ClutterBoxLayout *layout,
ClutterActor *actor);
CLUTTER_DEPRECATED
void clutter_box_layout_set_use_animations (ClutterBoxLayout *layout,
gboolean animate);
CLUTTER_DEPRECATED
gboolean clutter_box_layout_get_use_animations (ClutterBoxLayout *layout);
CLUTTER_DEPRECATED
void clutter_box_layout_set_easing_mode (ClutterBoxLayout *layout,
gulong mode);
CLUTTER_DEPRECATED
gulong clutter_box_layout_get_easing_mode (ClutterBoxLayout *layout);
CLUTTER_DEPRECATED
void clutter_box_layout_set_easing_duration (ClutterBoxLayout *layout,
guint msecs);
CLUTTER_DEPRECATED
guint clutter_box_layout_get_easing_duration (ClutterBoxLayout *layout);
G_END_DECLS G_END_DECLS

View File

@@ -23,12 +23,14 @@
*/ */
/** /**
* ClutterBrightnessContrastEffect: * SECTION:clutter-brightness-contrast-effect
* * @short_description: Increase/decrease brightness and/or contrast of actor.
* Increase/decrease brightness and/or contrast of actor. * @see_also: #ClutterEffect, #ClutterOffscreenEffect
* *
* #ClutterBrightnessContrastEffect is a sub-class of #ClutterEffect that * #ClutterBrightnessContrastEffect is a sub-class of #ClutterEffect that
* changes the overall brightness of a #ClutterActor. * changes the overall brightness of a #ClutterActor.
*
* #ClutterBrightnessContrastEffect is available since Clutter 1.10
*/ */
#define CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT, ClutterBrightnessContrastEffectClass)) #define CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT, ClutterBrightnessContrastEffectClass))
@@ -39,6 +41,8 @@
#include <math.h> #include <math.h>
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-brightness-contrast-effect.h" #include "clutter-brightness-contrast-effect.h"
#include <cogl/cogl.h> #include <cogl/cogl.h>
@@ -65,6 +69,9 @@ struct _ClutterBrightnessContrastEffect
gint brightness_offset_uniform; gint brightness_offset_uniform;
gint contrast_uniform; gint contrast_uniform;
gint tex_width;
gint tex_height;
CoglPipeline *pipeline; CoglPipeline *pipeline;
}; };
@@ -114,41 +121,80 @@ G_DEFINE_TYPE (ClutterBrightnessContrastEffect,
static gboolean static gboolean
will_have_no_effect (ClutterBrightnessContrastEffect *self) will_have_no_effect (ClutterBrightnessContrastEffect *self)
{ {
return (G_APPROX_VALUE (self->brightness_red, no_change, FLT_EPSILON) && return (self->brightness_red == no_change &&
G_APPROX_VALUE (self->brightness_green, no_change, FLT_EPSILON) && self->brightness_green == no_change &&
G_APPROX_VALUE (self->brightness_blue, no_change, FLT_EPSILON) && self->brightness_blue == no_change &&
G_APPROX_VALUE (self->contrast_red, no_change, FLT_EPSILON) && self->contrast_red == no_change &&
G_APPROX_VALUE (self->contrast_green, no_change, FLT_EPSILON) && self->contrast_green == no_change &&
G_APPROX_VALUE (self->contrast_blue, no_change, FLT_EPSILON)); self->contrast_blue == no_change);
}
static CoglPipeline *
clutter_brightness_contrast_effect_create_pipeline (ClutterOffscreenEffect *effect,
CoglTexture *texture)
{
ClutterBrightnessContrastEffect *self =
CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
return cogl_object_ref (self->pipeline);
} }
static gboolean static gboolean
clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect, clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect)
ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect); ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
ClutterEffectClass *parent_class; ClutterEffectClass *parent_class;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
return FALSE;
if (will_have_no_effect (self)) if (will_have_no_effect (self))
return FALSE; return FALSE;
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
{
/* if we don't have support for GLSL shaders then we
* forcibly disable the ActorMeta
*/
g_warning ("Unable to use the ClutterBrightnessContrastEffect: the "
"graphics hardware or the current GL driver does not "
"implement support for the GLSL shading language. The "
"effect will be disabled.");
clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE);
return FALSE;
}
parent_class = parent_class =
CLUTTER_EFFECT_CLASS (clutter_brightness_contrast_effect_parent_class); CLUTTER_EFFECT_CLASS (clutter_brightness_contrast_effect_parent_class);
if (parent_class->pre_paint (effect))
{
ClutterOffscreenEffect *offscreen_effect =
CLUTTER_OFFSCREEN_EFFECT (effect);
CoglHandle texture;
return parent_class->pre_paint (effect, node, paint_context); texture = clutter_offscreen_effect_get_texture (offscreen_effect);
self->tex_width = cogl_texture_get_width (texture);
self->tex_height = cogl_texture_get_height (texture);
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
return TRUE;
}
else
return FALSE;
}
static void
clutter_brightness_contrast_effect_paint_target (ClutterOffscreenEffect *effect)
{
ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
ClutterActor *actor;
guint8 paint_opacity;
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
paint_opacity = clutter_actor_get_paint_opacity (actor);
cogl_pipeline_set_color4ub (self->pipeline,
paint_opacity,
paint_opacity,
paint_opacity,
paint_opacity);
cogl_framebuffer_draw_rectangle (framebuffer,
self->pipeline,
0, 0,
self->tex_width, self->tex_height);
} }
static void static void
@@ -248,7 +294,7 @@ clutter_brightness_contrast_effect_class_init (ClutterBrightnessContrastEffectCl
ClutterOffscreenEffectClass *offscreen_class; ClutterOffscreenEffectClass *offscreen_class;
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
offscreen_class->create_pipeline = clutter_brightness_contrast_effect_create_pipeline; offscreen_class->paint_target = clutter_brightness_contrast_effect_paint_target;
effect_class->pre_paint = clutter_brightness_contrast_effect_pre_paint; effect_class->pre_paint = clutter_brightness_contrast_effect_pre_paint;
@@ -266,6 +312,8 @@ clutter_brightness_contrast_effect_class_init (ClutterBrightnessContrastEffectCl
* to indicate no change; values smaller than 127 indicate a decrease * to indicate no change; values smaller than 127 indicate a decrease
* in brightness, and values larger than 127 indicate an increase in * in brightness, and values larger than 127 indicate an increase in
* brightness. * brightness.
*
* Since: 1.10
*/ */
obj_props[PROP_BRIGHTNESS] = obj_props[PROP_BRIGHTNESS] =
clutter_param_spec_color ("brightness", clutter_param_spec_color ("brightness",
@@ -284,6 +332,8 @@ clutter_brightness_contrast_effect_class_init (ClutterBrightnessContrastEffectCl
* to indicate no change; values smaller than 127 indicate a decrease * to indicate no change; values smaller than 127 indicate a decrease
* in contrast, and values larger than 127 indicate an increase in * in contrast, and values larger than 127 indicate an increase in
* contrast. * contrast.
*
* Since: 1.10
*/ */
obj_props[PROP_CONTRAST] = obj_props[PROP_CONTRAST] =
clutter_param_spec_color ("contrast", clutter_param_spec_color ("contrast",
@@ -414,6 +464,8 @@ clutter_brightness_contrast_effect_init (ClutterBrightnessContrastEffect *self)
* Return value: (transfer full): the newly created * Return value: (transfer full): the newly created
* #ClutterBrightnessContrastEffect or %NULL. Use g_object_unref() when * #ClutterBrightnessContrastEffect or %NULL. Use g_object_unref() when
* done. * done.
*
* Since: 1.10
*/ */
ClutterEffect * ClutterEffect *
clutter_brightness_contrast_effect_new (void) clutter_brightness_contrast_effect_new (void)
@@ -431,6 +483,8 @@ clutter_brightness_contrast_effect_new (void)
* The range for each component is [-1.0, 1.0] where 0.0 designates no change, * 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 * values below 0.0 mean a decrease in brightness, and values above indicate
* an increase. * an increase.
*
* Since: 1.10
*/ */
void void
clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContrastEffect *effect, clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContrastEffect *effect,
@@ -440,9 +494,9 @@ clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContras
{ {
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect)); g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
if (G_APPROX_VALUE (red, effect->brightness_red, FLT_EPSILON) && if (red == effect->brightness_red &&
G_APPROX_VALUE (green, effect->brightness_green, FLT_EPSILON) && green == effect->brightness_green &&
G_APPROX_VALUE (blue, effect->brightness_blue, FLT_EPSILON)) blue == effect->brightness_blue)
return; return;
effect->brightness_red = red; effect->brightness_red = red;
@@ -467,6 +521,8 @@ clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContras
* change in brightness * change in brightness
* *
* Retrieves the change in brightness used by @effect. * Retrieves the change in brightness used by @effect.
*
* Since: 1.10
*/ */
void void
clutter_brightness_contrast_effect_get_brightness (ClutterBrightnessContrastEffect *effect, clutter_brightness_contrast_effect_get_brightness (ClutterBrightnessContrastEffect *effect,
@@ -494,6 +550,8 @@ clutter_brightness_contrast_effect_get_brightness (ClutterBrightnessContrastEffe
* The range of @brightness is [-1.0, 1.0], where 0.0 designates no change; * 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 * a value below 0.0 indicates a decrease in brightness; and a value
* above 0.0 indicates an increase of brightness. * above 0.0 indicates an increase of brightness.
*
* Since: 1.10
*/ */
void void
clutter_brightness_contrast_effect_set_brightness (ClutterBrightnessContrastEffect *effect, clutter_brightness_contrast_effect_set_brightness (ClutterBrightnessContrastEffect *effect,
@@ -515,6 +573,8 @@ clutter_brightness_contrast_effect_set_brightness (ClutterBrightnessContrastEffe
* The range for each component is [-1.0, 1.0] where 0.0 designates no change, * 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 * values below 0.0 mean a decrease in contrast, and values above indicate
* an increase. * an increase.
*
* Since: 1.10
*/ */
void void
clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastEffect *effect, clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastEffect *effect,
@@ -524,9 +584,9 @@ clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastE
{ {
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect)); g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
if (G_APPROX_VALUE (red, effect->contrast_red, FLT_EPSILON) && if (red == effect->contrast_red &&
G_APPROX_VALUE (green, effect->contrast_green, FLT_EPSILON) && green == effect->contrast_green &&
G_APPROX_VALUE (blue, effect->contrast_blue, FLT_EPSILON)) blue == effect->contrast_blue)
return; return;
effect->contrast_red = red; effect->contrast_red = red;
@@ -551,6 +611,8 @@ clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastE
* change in contrast * change in contrast
* *
* Retrieves the contrast value used by @effect. * Retrieves the contrast value used by @effect.
*
* Since: 1.10
*/ */
void void
clutter_brightness_contrast_effect_get_contrast (ClutterBrightnessContrastEffect *effect, clutter_brightness_contrast_effect_get_contrast (ClutterBrightnessContrastEffect *effect,
@@ -578,6 +640,8 @@ clutter_brightness_contrast_effect_get_contrast (ClutterBrightnessContrastEffect
* The range for @contrast is [-1.0, 1.0], where 0.0 designates no change; * 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 * a value below 0.0 indicates a decrease in contrast; and a value above
* 0.0 indicates an increase. * 0.0 indicates an increase.
*
* Since: 1.10
*/ */
void void
clutter_brightness_contrast_effect_set_contrast (ClutterBrightnessContrastEffect *effect, clutter_brightness_contrast_effect_set_contrast (ClutterBrightnessContrastEffect *effect,

View File

@@ -38,6 +38,14 @@ G_BEGIN_DECLS
#define CLUTTER_BRIGHTNESS_CONTRAST_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT, ClutterBrightnessContrastEffect)) #define CLUTTER_BRIGHTNESS_CONTRAST_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT, ClutterBrightnessContrastEffect))
#define CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT)) #define CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT))
/**
* ClutterBrightnessContrastEffect:
*
* #ClutterBrightnessContrastEffect is an opaque structure
* whose members cannot be directly accessed
*
* Since: 1.10
*/
typedef struct _ClutterBrightnessContrastEffect ClutterBrightnessContrastEffect; typedef struct _ClutterBrightnessContrastEffect ClutterBrightnessContrastEffect;
typedef struct _ClutterBrightnessContrastEffectClass ClutterBrightnessContrastEffectClass; typedef struct _ClutterBrightnessContrastEffectClass ClutterBrightnessContrastEffectClass;

View File

@@ -4,5 +4,11 @@
/* List of Cogl drivers */ /* List of Cogl drivers */
#mesondefine CLUTTER_DRIVERS #mesondefine CLUTTER_DRIVERS
/* Have evdev support for input handling */
#mesondefine HAVE_EVDEV
/* Building with libwacom for advanced tablet management */
#mesondefine HAVE_LIBWACOM
/* Supports PangoFt2 */ /* Supports PangoFt2 */
#mesondefine HAVE_PANGO_FT2 #mesondefine HAVE_PANGO_FT2

View File

@@ -40,13 +40,15 @@
* Utility function for setting the source color of @cr using * Utility function for setting the source color of @cr using
* a #ClutterColor. This function is the equivalent of: * a #ClutterColor. This function is the equivalent of:
* *
* ```c * |[
* cairo_set_source_rgba (cr, * cairo_set_source_rgba (cr,
* color->red / 255.0, * color->red / 255.0,
* color->green / 255.0, * color->green / 255.0,
* color->blue / 255.0, * color->blue / 255.0,
* color->alpha / 255.0); * color->alpha / 255.0);
* ``` * ]|
*
* Since: 1.0
*/ */
void void
clutter_cairo_set_source_color (cairo_t *cr, clutter_cairo_set_source_color (cairo_t *cr,
@@ -73,6 +75,8 @@ clutter_cairo_set_source_color (cairo_t *cr,
* @cr: a Cairo context * @cr: a Cairo context
* *
* Utility function to clear a Cairo context. * Utility function to clear a Cairo context.
*
* Since: 1.12
*/ */
void void
clutter_cairo_clear (cairo_t *cr) clutter_cairo_clear (cairo_t *cr)

View File

@@ -36,6 +36,8 @@ G_BEGIN_DECLS
* The #CoglPixelFormat to be used when uploading image data from * The #CoglPixelFormat to be used when uploading image data from
* and to a Cairo image surface using %CAIRO_FORMAT_ARGB32 and * and to a Cairo image surface using %CAIRO_FORMAT_ARGB32 and
* %CAIRO_FORMAT_RGB24 as #cairo_format_t. * %CAIRO_FORMAT_RGB24 as #cairo_format_t.
*
* Since: 1.8
*/ */
/* Cairo stores the data in native byte order as ARGB but Cogl's pixel /* Cairo stores the data in native byte order as ARGB but Cogl's pixel

View File

@@ -23,9 +23,10 @@
*/ */
/** /**
* ClutterCanvas: * SECTION:clutter-canvas
* * @Title: ClutterCanvas
* Content for 2D painting * @Short_Description: Content for 2D painting
* @See_Also: #ClutterContent
* *
* The #ClutterCanvas class is a #ClutterContent implementation that allows * The #ClutterCanvas class is a #ClutterContent implementation that allows
* drawing using the Cairo API on a 2D surface. * drawing using the Cairo API on a 2D surface.
@@ -36,7 +37,9 @@
* signal when invalidated using clutter_content_invalidate(). * signal when invalidated using clutter_content_invalidate().
* *
* See [canvas.c](https://git.gnome.org/browse/clutter/tree/examples/canvas.c?h=clutter-1.18) * See [canvas.c](https://git.gnome.org/browse/clutter/tree/examples/canvas.c?h=clutter-1.18)
* for an example of how to use #ClutterCanvas.. * for an example of how to use #ClutterCanvas.
*
* #ClutterCanvas is available since Clutter 1.10.
*/ */
#include "clutter-build-config.h" #include "clutter-build-config.h"
@@ -47,6 +50,8 @@
#include "clutter-canvas.h" #include "clutter-canvas.h"
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-actor-private.h" #include "clutter-actor-private.h"
#include "clutter-backend.h" #include "clutter-backend.h"
#include "clutter-cairo.h" #include "clutter-cairo.h"
@@ -232,6 +237,8 @@ clutter_canvas_class_init (ClutterCanvasClass *klass)
* ClutterCanvas:width: * ClutterCanvas:width:
* *
* The width of the canvas. * The width of the canvas.
*
* Since: 1.10
*/ */
obj_props[PROP_WIDTH] = obj_props[PROP_WIDTH] =
g_param_spec_int ("width", g_param_spec_int ("width",
@@ -246,6 +253,8 @@ clutter_canvas_class_init (ClutterCanvasClass *klass)
* ClutterCanvas:height: * ClutterCanvas:height:
* *
* The height of the canvas. * The height of the canvas.
*
* Since: 1.10
*/ */
obj_props[PROP_HEIGHT] = obj_props[PROP_HEIGHT] =
g_param_spec_int ("height", g_param_spec_int ("height",
@@ -286,6 +295,8 @@ clutter_canvas_class_init (ClutterCanvasClass *klass)
* *
* Return value: %TRUE if the signal emission should stop, and * Return value: %TRUE if the signal emission should stop, and
* %FALSE otherwise * %FALSE otherwise
*
* Since: 1.10
*/ */
canvas_signals[DRAW] = canvas_signals[DRAW] =
g_signal_new (I_("draw"), g_signal_new (I_("draw"),
@@ -319,8 +330,7 @@ clutter_canvas_init (ClutterCanvas *self)
static void static void
clutter_canvas_paint_content (ClutterContent *content, clutter_canvas_paint_content (ClutterContent *content,
ClutterActor *actor, ClutterActor *actor,
ClutterPaintNode *root, ClutterPaintNode *root)
ClutterPaintContext *paint_context)
{ {
ClutterCanvas *self = CLUTTER_CANVAS (content); ClutterCanvas *self = CLUTTER_CANVAS (content);
ClutterCanvasPrivate *priv = self->priv; ClutterCanvasPrivate *priv = self->priv;
@@ -333,13 +343,15 @@ clutter_canvas_paint_content (ClutterContent *content,
g_clear_pointer (&priv->texture, cogl_object_unref); g_clear_pointer (&priv->texture, cogl_object_unref);
if (priv->texture == NULL) if (priv->texture == NULL)
priv->texture = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (priv->buffer)); priv->texture = cogl_texture_new_from_bitmap (priv->buffer,
COGL_TEXTURE_NO_SLICING,
CLUTTER_CAIRO_FORMAT_ARGB32);
if (priv->texture == NULL) if (priv->texture == NULL)
return; return;
node = clutter_actor_create_texture_paint_node (actor, priv->texture); node = clutter_actor_create_texture_paint_node (actor, priv->texture);
clutter_paint_node_set_static_name (node, "Canvas Content"); clutter_paint_node_set_name (node, "Canvas Content");
clutter_paint_node_add_child (root, node); clutter_paint_node_add_child (root, node);
clutter_paint_node_unref (node); clutter_paint_node_unref (node);
@@ -502,6 +514,8 @@ clutter_content_iface_init (ClutterContentInterface *iface)
* *
* Return value: (transfer full): The newly allocated instance of * Return value: (transfer full): The newly allocated instance of
* #ClutterCanvas. Use g_object_unref() when done. * #ClutterCanvas. Use g_object_unref() when done.
*
* Since: 1.10
*/ */
ClutterContent * ClutterContent *
clutter_canvas_new (void) clutter_canvas_new (void)
@@ -564,13 +578,15 @@ clutter_canvas_invalidate_internal (ClutterCanvas *canvas,
* the size, you can use the return value of the function to conditionally * the size, you can use the return value of the function to conditionally
* call clutter_content_invalidate(): * call clutter_content_invalidate():
* *
* ```c * |[
* if (!clutter_canvas_set_size (canvas, width, height)) * if (!clutter_canvas_set_size (canvas, width, height))
* clutter_content_invalidate (CLUTTER_CONTENT (canvas)); * clutter_content_invalidate (CLUTTER_CONTENT (canvas));
* ``` * ]|
* *
* Return value: this function returns %TRUE if the size change * Return value: this function returns %TRUE if the size change
* caused a content invalidation, and %FALSE otherwise * caused a content invalidation, and %FALSE otherwise
*
* Since: 1.10
*/ */
gboolean gboolean
clutter_canvas_set_size (ClutterCanvas *canvas, clutter_canvas_set_size (ClutterCanvas *canvas,

View File

@@ -44,6 +44,15 @@ typedef struct _ClutterCanvas ClutterCanvas;
typedef struct _ClutterCanvasPrivate ClutterCanvasPrivate; typedef struct _ClutterCanvasPrivate ClutterCanvasPrivate;
typedef struct _ClutterCanvasClass ClutterCanvasClass; typedef struct _ClutterCanvasClass ClutterCanvasClass;
/**
* ClutterCanvas:
*
* The #ClutterCanvas structure contains
* private data and should only be accessed using the provided
* API.
*
* Since: 1.10
*/
struct _ClutterCanvas struct _ClutterCanvas
{ {
/*< private >*/ /*< private >*/
@@ -58,6 +67,8 @@ struct _ClutterCanvas
* *
* The #ClutterCanvasClass structure contains * The #ClutterCanvasClass structure contains
* private data. * private data.
*
* Since: 1.10
*/ */
struct _ClutterCanvasClass struct _ClutterCanvasClass
{ {

View File

@@ -25,43 +25,16 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>. * License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** /**
* ClutterChildMeta: * SECTION:clutter-child-meta
* @short_description: Wrapper for actors inside a container
* *
* Base interface for container specific state for child actors. * #ClutterChildMeta is a wrapper object created by #ClutterContainer
* implementations in order to store child-specific data and properties.
* *
* A child data is meant to be used when you need to keep track * A #ClutterChildMeta wraps a #ClutterActor inside a #ClutterContainer.
* of information about each individual child added to a container.
* *
* In order to use it you should create your own subclass of * #ClutterChildMeta is available since Clutter 0.8
* #ClutterChildMeta and set the #ClutterContainerIface child_meta_type
* interface member to your subclass type, like:
*
* ```c
* static void
* my_container_iface_init (ClutterContainerIface *iface)
* {
* // set the rest of the #ClutterContainer vtable
*
* container_iface->child_meta_type = MY_TYPE_CHILD_META;
* }
* ```
*
* This will automatically create a #ClutterChildMeta of type
* `MY_TYPE_CHILD_META` for every actor that is added to the container.
*
* The child data for an actor can be retrieved using the
* clutter_container_get_child_meta() function.
*
* The properties of the data and your subclass can be manipulated with
* clutter_container_child_set() and clutter_container_child_get() which
* act like g_object_set() and g_object_get().
*
* You can provide hooks for your own storage as well as control the
* instantiation by overriding the #ClutterContainerIface virtual functions
* #ClutterContainerIface.create_child_meta(), #ClutterContainerIface.destroy_child_meta(),
* and #ClutterContainerIface.get_child_meta().
*/ */
#include "clutter-build-config.h" #include "clutter-build-config.h"
@@ -145,6 +118,8 @@ clutter_child_meta_class_init (ClutterChildMetaClass *klass)
* ClutterChildMeta:container: * ClutterChildMeta:container:
* *
* The #ClutterContainer that created this #ClutterChildMeta. * The #ClutterContainer that created this #ClutterChildMeta.
*
* Since: 0.8
*/ */
obj_props[PROP_CONTAINER] = obj_props[PROP_CONTAINER] =
g_param_spec_object ("container", g_param_spec_object ("container",
@@ -158,6 +133,8 @@ clutter_child_meta_class_init (ClutterChildMetaClass *klass)
* ClutterChildMeta:actor: * ClutterChildMeta:actor:
* *
* The #ClutterActor being wrapped by this #ClutterChildMeta * The #ClutterActor being wrapped by this #ClutterChildMeta
*
* Since: 0.8
*/ */
obj_props[PROP_ACTOR] = obj_props[PROP_ACTOR] =
g_param_spec_object ("actor", g_param_spec_object ("actor",
@@ -184,6 +161,8 @@ clutter_child_meta_init (ClutterChildMeta *self)
* Retrieves the container using @data * Retrieves the container using @data
* *
* Return value: (transfer none): a #ClutterContainer * Return value: (transfer none): a #ClutterContainer
*
* Since: 0.8
*/ */
ClutterContainer * ClutterContainer *
clutter_child_meta_get_container (ClutterChildMeta *data) clutter_child_meta_get_container (ClutterChildMeta *data)
@@ -200,6 +179,8 @@ clutter_child_meta_get_container (ClutterChildMeta *data)
* Retrieves the actor wrapped by @data * Retrieves the actor wrapped by @data
* *
* Return value: (transfer none): a #ClutterActor * Return value: (transfer none): a #ClutterActor
*
* Since: 0.8
*/ */
ClutterActor * ClutterActor *
clutter_child_meta_get_actor (ClutterChildMeta *data) clutter_child_meta_get_actor (ClutterChildMeta *data)

View File

@@ -46,6 +46,46 @@ G_BEGIN_DECLS
typedef struct _ClutterChildMetaClass ClutterChildMetaClass; typedef struct _ClutterChildMetaClass ClutterChildMetaClass;
/**
* ClutterChildMeta:
* @container: the container handling this data
* @actor: the actor wrapped by this data
*
* Base interface for container specific state for child actors. A child
* data is meant to be used when you need to keep track of information
* about each individual child added to a container.
*
* In order to use it you should create your own subclass of
* #ClutterChildMeta and set the #ClutterContainerIface child_meta_type
* interface member to your subclass type, like:
*
* |[
* static void
* my_container_iface_init (ClutterContainerIface *iface)
* {
* // set the rest of the #ClutterContainer vtable
*
* container_iface->child_meta_type = MY_TYPE_CHILD_META;
* }
* ]|
*
* This will automatically create a #ClutterChildMeta of type
* `MY_TYPE_CHILD_META` for every actor that is added to the container.
*
* The child data for an actor can be retrieved using the
* clutter_container_get_child_meta() function.
*
* The properties of the data and your subclass can be manipulated with
* clutter_container_child_set() and clutter_container_child_get() which
* act like g_object_set() and g_object_get().
*
* You can provide hooks for your own storage as well as control the
* instantiation by overriding the #ClutterContainerIface virtual functions
* #ClutterContainerIface.create_child_meta(), #ClutterContainerIface.destroy_child_meta(),
* and #ClutterContainerIface.get_child_meta().
*
* Since: 0.8
*/
struct _ClutterChildMeta struct _ClutterChildMeta
{ {
/*< private >*/ /*< private >*/
@@ -60,6 +100,8 @@ struct _ClutterChildMeta
* ClutterChildMetaClass: * ClutterChildMetaClass:
* *
* The #ClutterChildMetaClass contains only private data * The #ClutterChildMetaClass contains only private data
*
* Since: 0.8
*/ */
struct _ClutterChildMetaClass struct _ClutterChildMetaClass
{ {

View File

@@ -23,39 +23,39 @@
*/ */
/** /**
* ClutterClickAction: * SECTION:clutter-click-action
* @Title: ClutterClickAction
* @Short_Description: Action for clickable actors
* *
* Action for clickable actors * #ClutterClickAction is a sub-class of #ClutterAction that implements
*
* #ClutterClickAction is a sub-class of [class@Action] that implements
* the logic for clickable actors, by using the low level events of * the logic for clickable actors, by using the low level events of
* [class@Actor], such as [signal@Actor::button-press-event] and * #ClutterActor, such as #ClutterActor::button-press-event and
* [signal@Actor::button-release-event], to synthesize the high level * #ClutterActor::button-release-event, to synthesize the high level
* [signal@ClickAction::clicked] signal. * #ClutterClickAction::clicked signal.
* *
* To use #ClutterClickAction you just need to apply it to a [class@Actor] * To use #ClutterClickAction you just need to apply it to a #ClutterActor
* using [method@Actor.add_action] and connect to the * using clutter_actor_add_action() and connect to the
* [signal@ClickAction::clicked] signal: * #ClutterClickAction::clicked signal:
* *
* ```c * |[
* ClutterAction *action = clutter_click_action_new (); * ClutterAction *action = clutter_click_action_new ();
* *
* clutter_actor_add_action (actor, action); * clutter_actor_add_action (actor, action);
* *
* g_signal_connect (action, "clicked", G_CALLBACK (on_clicked), NULL); * g_signal_connect (action, "clicked", G_CALLBACK (on_clicked), NULL);
* ``` * ]|
* *
* #ClutterClickAction also supports long press gestures: a long press is * #ClutterClickAction also supports long press gestures: a long press is
* activated if the pointer remains pressed within a certain threshold (as * activated if the pointer remains pressed within a certain threshold (as
* defined by the [property@ClickAction:long-press-threshold] property) for a * defined by the #ClutterClickAction:long-press-threshold property) for a
* minimum amount of time (as the defined by the * minimum amount of time (as the defined by the
* [property@ClickAction:long-press-duration] property). * #ClutterClickAction:long-press-duration property).
* The [signal@ClickAction::long-press] signal is emitted multiple times, * The #ClutterClickAction::long-press signal is emitted multiple times,
* using different [enum@LongPressState] values; to handle long presses * using different #ClutterLongPressState values; to handle long presses
* you should connect to the [signal@ClickAction::long-press] signal and * you should connect to the #ClutterClickAction::long-press signal and
* handle the different states: * handle the different states:
* *
* ```c * |[
* static gboolean * static gboolean
* on_long_press (ClutterClickAction *action, * on_long_press (ClutterClickAction *action,
* ClutterActor *actor, * ClutterActor *actor,
@@ -64,27 +64,32 @@
* switch (state) * switch (state)
* { * {
* case CLUTTER_LONG_PRESS_QUERY: * case CLUTTER_LONG_PRESS_QUERY:
* // return TRUE if the actor should support long press * /&ast; return TRUE if the actor should support long press
* // gestures, and FALSE otherwise; this state will be * &ast; gestures, and FALSE otherwise; this state will be
* // emitted on button presses * &ast; emitted on button presses
* &ast;/
* return TRUE; * return TRUE;
* *
* case CLUTTER_LONG_PRESS_ACTIVATE: * case CLUTTER_LONG_PRESS_ACTIVATE:
* // this state is emitted if the minimum duration has * /&ast; this state is emitted if the minimum duration has
* // been reached without the gesture being cancelled. * &ast; been reached without the gesture being cancelled.
* // the return value is not used * &ast; the return value is not used
* &ast;/
* return TRUE; * return TRUE;
* *
* case CLUTTER_LONG_PRESS_CANCEL: * case CLUTTER_LONG_PRESS_CANCEL:
* // this state is emitted if the long press was cancelled; * /&ast; this state is emitted if the long press was cancelled;
* // for instance, the pointer went outside the actor or the * &ast; for instance, the pointer went outside the actor or the
* // allowed threshold, or the button was released before * &ast; allowed threshold, or the button was released before
* // the minimum duration was reached. the return value is * &ast; the minimum duration was reached. the return value is
* // not used * &ast; not used
* &ast;/
* return FALSE; * return FALSE;
* } * }
* } * }
* ``` * ]|
*
* #ClutterClickAction is available since Clutter 1.4
*/ */
#include "clutter-build-config.h" #include "clutter-build-config.h"
@@ -100,6 +105,8 @@ struct _ClutterClickActionPrivate
{ {
ClutterActor *stage; ClutterActor *stage;
guint event_id;
guint capture_id;
guint long_press_id; guint long_press_id;
gint long_press_threshold; gint long_press_threshold;
@@ -107,7 +114,7 @@ struct _ClutterClickActionPrivate
gint drag_threshold; gint drag_threshold;
guint press_button; guint press_button;
ClutterInputDevice *press_device; gint press_device_id;
ClutterEventSequence *press_sequence; ClutterEventSequence *press_sequence;
ClutterModifierType modifier_state; ClutterModifierType modifier_state;
gfloat press_x; gfloat press_x;
@@ -143,12 +150,16 @@ static guint click_signals[LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE_WITH_PRIVATE (ClutterClickAction, clutter_click_action, CLUTTER_TYPE_ACTION) G_DEFINE_TYPE_WITH_PRIVATE (ClutterClickAction, clutter_click_action, CLUTTER_TYPE_ACTION)
/* forward declaration */
static gboolean on_captured_event (ClutterActor *stage,
ClutterEvent *event,
ClutterClickAction *action);
static inline void static inline void
click_action_set_pressed (ClutterClickAction *action, click_action_set_pressed (ClutterClickAction *action,
gboolean is_pressed) gboolean is_pressed)
{ {
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = action->priv;
clutter_click_action_get_instance_private (action);
is_pressed = !!is_pressed; is_pressed = !!is_pressed;
@@ -163,8 +174,7 @@ static inline void
click_action_set_held (ClutterClickAction *action, click_action_set_held (ClutterClickAction *action,
gboolean is_held) gboolean is_held)
{ {
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = action->priv;
clutter_click_action_get_instance_private (action);
is_held = !!is_held; is_held = !!is_held;
@@ -179,8 +189,7 @@ static gboolean
click_action_emit_long_press (gpointer data) click_action_emit_long_press (gpointer data)
{ {
ClutterClickAction *action = data; ClutterClickAction *action = data;
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = action->priv;
clutter_click_action_get_instance_private (action);
ClutterActor *actor; ClutterActor *actor;
gboolean result; gboolean result;
@@ -193,6 +202,12 @@ click_action_emit_long_press (gpointer data)
CLUTTER_LONG_PRESS_ACTIVATE, CLUTTER_LONG_PRESS_ACTIVATE,
&result); &result);
if (priv->capture_id != 0)
{
g_signal_handler_disconnect (priv->stage, priv->capture_id);
priv->capture_id = 0;
}
click_action_set_pressed (action, FALSE); click_action_set_pressed (action, FALSE);
click_action_set_held (action, FALSE); click_action_set_held (action, FALSE);
@@ -202,8 +217,7 @@ click_action_emit_long_press (gpointer data)
static inline void static inline void
click_action_query_long_press (ClutterClickAction *action) click_action_query_long_press (ClutterClickAction *action)
{ {
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = action->priv;
clutter_click_action_get_instance_private (action);
ClutterActor *actor; ClutterActor *actor;
gboolean result = FALSE; gboolean result = FALSE;
gint timeout; gint timeout;
@@ -228,7 +242,6 @@ click_action_query_long_press (ClutterClickAction *action)
if (result) if (result)
{ {
g_clear_handle_id (&priv->long_press_id, g_source_remove);
priv->long_press_id = priv->long_press_id =
clutter_threads_add_timeout (timeout, clutter_threads_add_timeout (timeout,
click_action_emit_long_press, click_action_emit_long_press,
@@ -239,8 +252,7 @@ click_action_query_long_press (ClutterClickAction *action)
static inline void static inline void
click_action_cancel_long_press (ClutterClickAction *action) click_action_cancel_long_press (ClutterClickAction *action)
{ {
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = action->priv;
clutter_click_action_get_instance_private (action);
if (priv->long_press_id != 0) if (priv->long_press_id != 0)
{ {
@@ -249,7 +261,8 @@ click_action_cancel_long_press (ClutterClickAction *action)
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
g_clear_handle_id (&priv->long_press_id, g_source_remove); g_source_remove (priv->long_press_id);
priv->long_press_id = 0;
g_signal_emit (action, click_signals[LONG_PRESS], 0, g_signal_emit (action, click_signals[LONG_PRESS], 0,
actor, actor,
@@ -258,66 +271,33 @@ click_action_cancel_long_press (ClutterClickAction *action)
} }
} }
static inline gboolean
event_within_drag_threshold (ClutterClickAction *click_action,
const ClutterEvent *event)
{
ClutterClickActionPrivate *priv =
clutter_click_action_get_instance_private (click_action);
float motion_x, motion_y;
float delta_x, delta_y;
clutter_event_get_coords (event, &motion_x, &motion_y);
delta_x = ABS (motion_x - priv->press_x);
delta_y = ABS (motion_y - priv->press_y);
return delta_x <= priv->drag_threshold && delta_y <= priv->drag_threshold;
}
static gboolean static gboolean
clutter_click_action_handle_event (ClutterAction *action, on_event (ClutterActor *actor,
const ClutterEvent *event) ClutterEvent *event,
ClutterClickAction *action)
{ {
ClutterClickAction *click_action = CLUTTER_CLICK_ACTION (action); ClutterClickActionPrivate *priv = action->priv;
ClutterClickActionPrivate *priv =
clutter_click_action_get_instance_private (click_action);
ClutterActor *actor =
clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
gboolean has_button = TRUE; gboolean has_button = TRUE;
ClutterModifierType modifier_state;
ClutterActor *target;
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action))) if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
return CLUTTER_EVENT_PROPAGATE; 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)) switch (clutter_event_type (event))
{ {
case CLUTTER_TOUCH_BEGIN: case CLUTTER_TOUCH_BEGIN:
has_button = FALSE; has_button = FALSE;
G_GNUC_FALLTHROUGH;
case CLUTTER_BUTTON_PRESS: case CLUTTER_BUTTON_PRESS:
if (has_button && clutter_event_get_click_count (event) != 1)
return CLUTTER_EVENT_PROPAGATE;
if (priv->is_held) if (priv->is_held)
return CLUTTER_EVENT_STOP; return CLUTTER_EVENT_STOP;
target = clutter_stage_get_device_actor (clutter_event_get_stage (event), if (!clutter_actor_contains (actor, clutter_event_get_source (event)))
clutter_event_get_device (event),
clutter_event_get_event_sequence (event));
if (!clutter_actor_contains (actor, target))
return CLUTTER_EVENT_PROPAGATE; return CLUTTER_EVENT_PROPAGATE;
priv->press_button = has_button ? clutter_event_get_button (event) : 0; priv->press_button = has_button ? clutter_event_get_button (event) : 0;
priv->press_device = clutter_event_get_device (event); priv->press_device_id = clutter_event_get_device_id (event);
priv->press_sequence = clutter_event_get_event_sequence (event); priv->press_sequence = clutter_event_get_event_sequence (event);
priv->modifier_state = clutter_event_get_state (event); priv->modifier_state = clutter_event_get_state (event);
clutter_event_get_coords (event, &priv->press_x, &priv->press_y); clutter_event_get_coords (event, &priv->press_x, &priv->press_y);
@@ -336,47 +316,78 @@ clutter_click_action_handle_event (ClutterAction *action,
if (priv->stage == NULL) if (priv->stage == NULL)
priv->stage = clutter_actor_get_stage (actor); priv->stage = clutter_actor_get_stage (actor);
click_action_set_pressed (click_action, TRUE); priv->capture_id = g_signal_connect_after (priv->stage, "captured-event",
click_action_set_held (click_action, TRUE); G_CALLBACK (on_captured_event),
click_action_query_long_press (click_action); action);
click_action_set_pressed (action, TRUE);
click_action_set_held (action, TRUE);
click_action_query_long_press (action);
break; break;
case CLUTTER_ENTER: case CLUTTER_ENTER:
click_action_set_pressed (click_action, priv->is_held); click_action_set_pressed (action, priv->is_held);
break; break;
case CLUTTER_LEAVE: case CLUTTER_LEAVE:
click_action_set_pressed (click_action, FALSE); click_action_set_pressed (action, priv->is_held);
click_action_cancel_long_press (click_action); click_action_cancel_long_press (action);
break; break;
default:
break;
}
return CLUTTER_EVENT_PROPAGATE;
}
static gboolean
on_captured_event (ClutterActor *stage,
ClutterEvent *event,
ClutterClickAction *action)
{
ClutterClickActionPrivate *priv = action->priv;
ClutterActor *actor;
ClutterModifierType modifier_state;
gboolean has_button = TRUE;
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
switch (clutter_event_type (event))
{
case CLUTTER_TOUCH_CANCEL: case CLUTTER_TOUCH_CANCEL:
clutter_click_action_release (click_action); clutter_click_action_release (action);
break; break;
case CLUTTER_TOUCH_END: case CLUTTER_TOUCH_END:
has_button = FALSE; has_button = FALSE;
G_GNUC_FALLTHROUGH;
case CLUTTER_BUTTON_RELEASE: case CLUTTER_BUTTON_RELEASE:
if (!priv->is_held) if (!priv->is_held)
return CLUTTER_EVENT_PROPAGATE; return CLUTTER_EVENT_STOP;
if ((has_button && clutter_event_get_button (event) != priv->press_button) || if ((has_button && clutter_event_get_button (event) != priv->press_button) ||
clutter_event_get_device (event) != priv->press_device || (has_button && clutter_event_get_click_count (event) != 1) ||
clutter_event_get_device_id (event) != priv->press_device_id ||
clutter_event_get_event_sequence (event) != priv->press_sequence) clutter_event_get_event_sequence (event) != priv->press_sequence)
return CLUTTER_EVENT_PROPAGATE; return CLUTTER_EVENT_PROPAGATE;
click_action_set_held (click_action, FALSE); click_action_set_held (action, FALSE);
click_action_cancel_long_press (click_action); click_action_cancel_long_press (action);
g_clear_handle_id (&priv->long_press_id, g_source_remove); /* disconnect the capture */
if (priv->capture_id != 0)
{
g_signal_handler_disconnect (priv->stage, priv->capture_id);
priv->capture_id = 0;
}
target = clutter_stage_get_device_actor (clutter_event_get_stage (event), if (priv->long_press_id != 0)
clutter_event_get_device (event), {
clutter_event_get_event_sequence (event)); g_source_remove (priv->long_press_id);
priv->long_press_id = 0;
}
if (!clutter_actor_contains (actor, target)) if (!clutter_actor_contains (actor, clutter_event_get_source (event)))
return CLUTTER_EVENT_PROPAGATE; return CLUTTER_EVENT_PROPAGATE;
/* exclude any button-mask so that we can compare /* exclude any button-mask so that we can compare
@@ -395,24 +406,31 @@ clutter_click_action_handle_event (ClutterAction *action,
if (modifier_state != priv->modifier_state) if (modifier_state != priv->modifier_state)
priv->modifier_state = 0; priv->modifier_state = 0;
click_action_set_pressed (click_action, FALSE); click_action_set_pressed (action, FALSE);
g_signal_emit (action, click_signals[CLICKED], 0, actor);
if (event_within_drag_threshold (click_action, event))
g_signal_emit (click_action, click_signals[CLICKED], 0, actor);
break; break;
case CLUTTER_MOTION: case CLUTTER_MOTION:
case CLUTTER_TOUCH_UPDATE: case CLUTTER_TOUCH_UPDATE:
{ {
if (clutter_event_get_device (event) != priv->press_device || gfloat motion_x, motion_y;
gfloat delta_x, delta_y;
if (clutter_event_get_device_id (event) != priv->press_device_id ||
clutter_event_get_event_sequence (event) != priv->press_sequence) clutter_event_get_event_sequence (event) != priv->press_sequence)
return CLUTTER_EVENT_PROPAGATE; return CLUTTER_EVENT_PROPAGATE;
if (!priv->is_held) if (!priv->is_held)
return CLUTTER_EVENT_PROPAGATE; return CLUTTER_EVENT_PROPAGATE;
if (!event_within_drag_threshold (click_action, event)) clutter_event_get_coords (event, &motion_x, &motion_y);
clutter_click_action_release (click_action);
delta_x = ABS (motion_x - priv->press_x);
delta_y = ABS (motion_y - priv->press_y);
if (delta_x > priv->drag_threshold ||
delta_y > priv->drag_threshold)
click_action_cancel_long_press (action);
} }
break; break;
@@ -420,7 +438,7 @@ clutter_click_action_handle_event (ClutterAction *action,
break; break;
} }
return priv->is_held ? CLUTTER_EVENT_STOP : CLUTTER_EVENT_PROPAGATE; return CLUTTER_EVENT_STOP;
} }
static void static void
@@ -428,39 +446,51 @@ clutter_click_action_set_actor (ClutterActorMeta *meta,
ClutterActor *actor) ClutterActor *actor)
{ {
ClutterClickAction *action = CLUTTER_CLICK_ACTION (meta); ClutterClickAction *action = CLUTTER_CLICK_ACTION (meta);
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = action->priv;
clutter_click_action_get_instance_private (action);
g_clear_handle_id (&priv->long_press_id, g_source_remove); if (priv->event_id != 0)
{
ClutterActor *old_actor = clutter_actor_meta_get_actor (meta);
if (old_actor != NULL)
g_signal_handler_disconnect (old_actor, priv->event_id);
priv->event_id = 0;
}
if (priv->capture_id != 0)
{
if (priv->stage != NULL)
g_signal_handler_disconnect (priv->stage, priv->capture_id);
priv->capture_id = 0;
priv->stage = NULL;
}
if (priv->long_press_id != 0)
{
g_source_remove (priv->long_press_id);
priv->long_press_id = 0;
}
click_action_set_pressed (action, FALSE); click_action_set_pressed (action, FALSE);
click_action_set_held (action, FALSE); click_action_set_held (action, FALSE);
if (actor != NULL)
priv->event_id = g_signal_connect (actor, "event",
G_CALLBACK (on_event),
action);
CLUTTER_ACTOR_META_CLASS (clutter_click_action_parent_class)->set_actor (meta, actor); 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 static void
clutter_click_action_set_property (GObject *gobject, clutter_click_action_set_property (GObject *gobject,
guint prop_id, guint prop_id,
const GValue *value, const GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv;
clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
switch (prop_id) switch (prop_id)
{ {
@@ -484,8 +514,7 @@ clutter_click_action_get_property (GObject *gobject,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv;
clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
switch (prop_id) switch (prop_id)
{ {
@@ -514,25 +543,38 @@ clutter_click_action_get_property (GObject *gobject,
static void static void
clutter_click_action_dispose (GObject *gobject) clutter_click_action_dispose (GObject *gobject)
{ {
ClutterClickActionPrivate *priv = ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv;
clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
g_clear_handle_id (&priv->long_press_id, g_source_remove); if (priv->event_id)
{
g_signal_handler_disconnect (clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (gobject)),
priv->event_id);
priv->event_id = 0;
}
if (priv->capture_id)
{
g_signal_handler_disconnect (priv->stage, priv->capture_id);
priv->capture_id = 0;
}
if (priv->long_press_id)
{
g_source_remove (priv->long_press_id);
priv->long_press_id = 0;
}
G_OBJECT_CLASS (clutter_click_action_parent_class)->dispose (gobject); G_OBJECT_CLASS (clutter_click_action_parent_class)->dispose (gobject);
} }
static void static void
clutter_click_action_class_init (ClutterClickActionClass *klass) clutter_click_action_class_init (ClutterClickActionClass *klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
ClutterActionClass *action_class = CLUTTER_ACTION_CLASS (klass);
action_class->handle_event = clutter_click_action_handle_event;
meta_class->set_actor = clutter_click_action_set_actor; meta_class->set_actor = clutter_click_action_set_actor;
meta_class->set_enabled = clutter_click_action_set_enabled;
gobject_class->dispose = clutter_click_action_dispose; gobject_class->dispose = clutter_click_action_dispose;
gobject_class->set_property = clutter_click_action_set_property; gobject_class->set_property = clutter_click_action_set_property;
@@ -542,6 +584,8 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
* ClutterClickAction:pressed: * ClutterClickAction:pressed:
* *
* Whether the clickable actor should be in "pressed" state * Whether the clickable actor should be in "pressed" state
*
* Since: 1.4
*/ */
obj_props[PROP_PRESSED] = obj_props[PROP_PRESSED] =
g_param_spec_boolean ("pressed", g_param_spec_boolean ("pressed",
@@ -554,6 +598,8 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
* ClutterClickAction:held: * ClutterClickAction:held:
* *
* Whether the clickable actor has the pointer grabbed * Whether the clickable actor has the pointer grabbed
*
* Since: 1.4
*/ */
obj_props[PROP_HELD] = obj_props[PROP_HELD] =
g_param_spec_boolean ("held", g_param_spec_boolean ("held",
@@ -569,7 +615,9 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
* press gesture, in milliseconds. * press gesture, in milliseconds.
* *
* A value of -1 will make the #ClutterClickAction use the value of * A value of -1 will make the #ClutterClickAction use the value of
* the [property@Settings:long-press-duration] property. * the #ClutterSettings:long-press-duration property.
*
* Since: 1.8
*/ */
obj_props[PROP_LONG_PRESS_DURATION] = obj_props[PROP_LONG_PRESS_DURATION] =
g_param_spec_int ("long-press-duration", g_param_spec_int ("long-press-duration",
@@ -586,7 +634,9 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
* a long press gesture is cancelled, in pixels. * a long press gesture is cancelled, in pixels.
* *
* A value of -1 will make the #ClutterClickAction use the value of * A value of -1 will make the #ClutterClickAction use the value of
* the [property@Settings:dnd-drag-threshold] property. * the #ClutterSettings:dnd-drag-threshold property.
*
* Since: 1.8
*/ */
obj_props[PROP_LONG_PRESS_THRESHOLD] = obj_props[PROP_LONG_PRESS_THRESHOLD] =
g_param_spec_int ("long-press-threshold", g_param_spec_int ("long-press-threshold",
@@ -605,9 +655,11 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
* @action: the #ClutterClickAction that emitted the signal * @action: the #ClutterClickAction that emitted the signal
* @actor: the #ClutterActor attached to the @action * @actor: the #ClutterActor attached to the @action
* *
* The signal is emitted when the [class@Actor] to which * The ::clicked signal is emitted when the #ClutterActor to which
* a #ClutterClickAction has been applied should respond to a * a #ClutterClickAction has been applied should respond to a
* pointer button press and release events * pointer button press and release events
*
* Since: 1.4
*/ */
click_signals[CLICKED] = click_signals[CLICKED] =
g_signal_new (I_("clicked"), g_signal_new (I_("clicked"),
@@ -624,7 +676,7 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
* @actor: the #ClutterActor attached to the @action * @actor: the #ClutterActor attached to the @action
* @state: the long press state * @state: the long press state
* *
* The signal is emitted during the long press gesture * The ::long-press signal is emitted during the long press gesture
* handling. * handling.
* *
* This signal can be emitted multiple times with different states. * This signal can be emitted multiple times with different states.
@@ -638,10 +690,12 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
* %CLUTTER_LONG_PRESS_CANCEL state if the long press was cancelled. * %CLUTTER_LONG_PRESS_CANCEL state if the long press was cancelled.
* *
* It is possible to forcibly cancel a long press detection using * It is possible to forcibly cancel a long press detection using
* [method@ClickAction.release]. * clutter_click_action_release().
* *
* Return value: Only the %CLUTTER_LONG_PRESS_QUERY state uses the * Return value: Only the %CLUTTER_LONG_PRESS_QUERY state uses the
* returned value of the handler; other states will ignore it * returned value of the handler; other states will ignore it
*
* Since: 1.8
*/ */
click_signals[LONG_PRESS] = click_signals[LONG_PRESS] =
g_signal_new (I_("long-press"), g_signal_new (I_("long-press"),
@@ -658,11 +712,9 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
static void static void
clutter_click_action_init (ClutterClickAction *self) clutter_click_action_init (ClutterClickAction *self)
{ {
ClutterClickActionPrivate *priv = self->priv = clutter_click_action_get_instance_private (self);
clutter_click_action_get_instance_private (self); self->priv->long_press_threshold = -1;
self->priv->long_press_duration = -1;
priv->long_press_threshold = -1;
priv->long_press_duration = -1;
} }
/** /**
@@ -671,6 +723,8 @@ clutter_click_action_init (ClutterClickAction *self)
* Creates a new #ClutterClickAction instance * Creates a new #ClutterClickAction instance
* *
* Return value: the newly created #ClutterClickAction * Return value: the newly created #ClutterClickAction
*
* Since: 1.4
*/ */
ClutterAction * ClutterAction *
clutter_click_action_new (void) clutter_click_action_new (void)
@@ -683,13 +737,15 @@ clutter_click_action_new (void)
* @action: a #ClutterClickAction * @action: a #ClutterClickAction
* *
* Emulates a release of the pointer button, which ungrabs the pointer * Emulates a release of the pointer button, which ungrabs the pointer
* and unsets the [property@ClickAction:pressed] state. * and unsets the #ClutterClickAction:pressed state.
* *
* This function will also cancel the long press gesture if one was * This function will also cancel the long press gesture if one was
* initiated. * initiated.
* *
* This function is useful to break a grab, for instance after a certain * This function is useful to break a grab, for instance after a certain
* amount of time has passed. * amount of time has passed.
*
* Since: 1.4
*/ */
void void
clutter_click_action_release (ClutterClickAction *action) clutter_click_action_release (ClutterClickAction *action)
@@ -698,11 +754,18 @@ clutter_click_action_release (ClutterClickAction *action)
g_return_if_fail (CLUTTER_IS_CLICK_ACTION (action)); g_return_if_fail (CLUTTER_IS_CLICK_ACTION (action));
priv = clutter_click_action_get_instance_private (action); priv = action->priv;
if (!priv->is_held) if (!priv->is_held)
return; return;
/* disconnect the capture */
if (priv->capture_id != 0)
{
g_signal_handler_disconnect (priv->stage, priv->capture_id);
priv->capture_id = 0;
}
click_action_cancel_long_press (action); click_action_cancel_long_press (action);
click_action_set_held (action, FALSE); click_action_set_held (action, FALSE);
click_action_set_pressed (action, FALSE); click_action_set_pressed (action, FALSE);
@@ -715,17 +778,15 @@ clutter_click_action_release (ClutterClickAction *action)
* Retrieves the button that was pressed. * Retrieves the button that was pressed.
* *
* Return value: the button value * Return value: the button value
*
* Since: 1.4
*/ */
guint guint
clutter_click_action_get_button (ClutterClickAction *action) clutter_click_action_get_button (ClutterClickAction *action)
{ {
ClutterClickActionPrivate *priv;
g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0); g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0);
priv = clutter_click_action_get_instance_private (action); return action->priv->press_button;
return priv->press_button;
} }
/** /**
@@ -735,17 +796,15 @@ clutter_click_action_get_button (ClutterClickAction *action)
* Retrieves the modifier state of the click action. * Retrieves the modifier state of the click action.
* *
* Return value: the modifier state parameter, or 0 * Return value: the modifier state parameter, or 0
*
* Since: 1.6
*/ */
ClutterModifierType ClutterModifierType
clutter_click_action_get_state (ClutterClickAction *action) clutter_click_action_get_state (ClutterClickAction *action)
{ {
ClutterClickActionPrivate *priv;
g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0); g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0);
priv = clutter_click_action_get_instance_private (action); return action->priv->modifier_state;
return priv->modifier_state;
} }
/** /**
@@ -755,21 +814,19 @@ clutter_click_action_get_state (ClutterClickAction *action)
* @press_y: (out): return location for the Y coordinate, or %NULL * @press_y: (out): return location for the Y coordinate, or %NULL
* *
* Retrieves the screen coordinates of the button press. * Retrieves the screen coordinates of the button press.
*
* Since: 1.8
*/ */
void void
clutter_click_action_get_coords (ClutterClickAction *action, clutter_click_action_get_coords (ClutterClickAction *action,
gfloat *press_x, gfloat *press_x,
gfloat *press_y) gfloat *press_y)
{ {
ClutterClickActionPrivate *priv;
g_return_if_fail (CLUTTER_IS_ACTION (action)); g_return_if_fail (CLUTTER_IS_ACTION (action));
priv = clutter_click_action_get_instance_private (action);
if (press_x != NULL) if (press_x != NULL)
*press_x = priv->press_x; *press_x = action->priv->press_x;
if (press_y != NULL) if (press_y != NULL)
*press_y = priv->press_y; *press_y = action->priv->press_y;
} }

View File

@@ -38,12 +38,31 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define CLUTTER_TYPE_CLICK_ACTION (clutter_click_action_get_type ()) #define CLUTTER_TYPE_CLICK_ACTION (clutter_click_action_get_type ())
#define CLUTTER_CLICK_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CLICK_ACTION, ClutterClickAction))
#define CLUTTER_IS_CLICK_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CLICK_ACTION))
#define CLUTTER_CLICK_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CLICK_ACTION, ClutterClickActionClass))
#define CLUTTER_IS_CLICK_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CLICK_ACTION))
#define CLUTTER_CLICK_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CLICK_ACTION, ClutterClickActionClass))
CLUTTER_EXPORT typedef struct _ClutterClickAction ClutterClickAction;
G_DECLARE_DERIVABLE_TYPE (ClutterClickAction, clutter_click_action,
CLUTTER, CLICK_ACTION, ClutterAction);
typedef struct _ClutterClickActionPrivate ClutterClickActionPrivate; typedef struct _ClutterClickActionPrivate ClutterClickActionPrivate;
typedef struct _ClutterClickActionClass ClutterClickActionClass;
/**
* ClutterClickAction:
*
* The #ClutterClickAction structure contains
* only private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _ClutterClickAction
{
/*< private >*/
ClutterAction parent_instance;
ClutterClickActionPrivate *priv;
};
/** /**
* ClutterClickActionClass: * ClutterClickActionClass:
@@ -52,6 +71,8 @@ typedef struct _ClutterClickActionPrivate ClutterClickActionPrivate;
* *
* The #ClutterClickActionClass structure * The #ClutterClickActionClass structure
* contains only private data * contains only private data
*
* Since: 1.4
*/ */
struct _ClutterClickActionClass struct _ClutterClickActionClass
{ {
@@ -76,6 +97,9 @@ struct _ClutterClickActionClass
void (* _clutter_click_action7) (void); void (* _clutter_click_action7) (void);
}; };
CLUTTER_EXPORT
GType clutter_click_action_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT CLUTTER_EXPORT
ClutterAction * clutter_click_action_new (void); ClutterAction * clutter_click_action_new (void);

View File

@@ -22,9 +22,8 @@
*/ */
/** /**
* ClutterClone: * SECTION:clutter-clone
* * @short_description: An actor that displays a clone of a source actor
* An actor that displays a clone of a source actor
* *
* #ClutterClone is a #ClutterActor which draws with the paint * #ClutterClone is a #ClutterActor which draws with the paint
* function of another actor, scaled to fit its own allocation. * function of another actor, scaled to fit its own allocation.
@@ -34,10 +33,13 @@
* Unlike clutter_texture_new_from_actor(), #ClutterClone does not require * Unlike clutter_texture_new_from_actor(), #ClutterClone does not require
* the presence of support for FBOs in the underlying GL or GLES * the presence of support for FBOs in the underlying GL or GLES
* implementation. * implementation.
*
* #ClutterClone is available since Clutter 1.0
*/ */
#include "clutter-build-config.h" #include "clutter-build-config.h"
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-actor-private.h" #include "clutter-actor-private.h"
#include "clutter-clone.h" #include "clutter-clone.h"
#include "clutter-debug.h" #include "clutter-debug.h"
@@ -50,8 +52,6 @@
struct _ClutterClonePrivate struct _ClutterClonePrivate
{ {
ClutterActor *clone_source; ClutterActor *clone_source;
float x_scale, y_scale;
gulong source_destroy_id; gulong source_destroy_id;
}; };
@@ -119,22 +119,40 @@ clutter_clone_get_preferred_height (ClutterActor *self,
} }
static void static void
clutter_clone_apply_transform (ClutterActor *self, clutter_clone_apply_transform (ClutterActor *self, CoglMatrix *matrix)
graphene_matrix_t *matrix)
{ {
ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv; ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
ClutterActorBox box, source_box;
gfloat x_scale, y_scale;
/* First chain up and apply all the standard ClutterActor
if (priv->clone_source) * transformations... */
graphene_matrix_scale (matrix, priv->x_scale, priv->y_scale, 1.f);
CLUTTER_ACTOR_CLASS (clutter_clone_parent_class)->apply_transform (self, CLUTTER_ACTOR_CLASS (clutter_clone_parent_class)->apply_transform (self,
matrix); matrix);
/* if we don't have a source, nothing else to do */
if (priv->clone_source == NULL)
return;
/* get our allocated size */
clutter_actor_get_allocation_box (self, &box);
/* and get the allocated size of the source */
clutter_actor_get_allocation_box (priv->clone_source, &source_box);
/* We need to scale what the clone-source actor paints to fill our own
* allocation...
*/
x_scale = clutter_actor_box_get_width (&box)
/ clutter_actor_box_get_width (&source_box);
y_scale = clutter_actor_box_get_height (&box)
/ clutter_actor_box_get_height (&source_box);
cogl_matrix_scale (matrix, x_scale, y_scale, x_scale);
} }
static void static void
clutter_clone_paint (ClutterActor *actor, clutter_clone_paint (ClutterActor *actor)
ClutterPaintContext *paint_context)
{ {
ClutterClone *self = CLUTTER_CLONE (actor); ClutterClone *self = CLUTTER_CLONE (actor);
ClutterClonePrivate *priv = self->priv; ClutterClonePrivate *priv = self->priv;
@@ -171,7 +189,7 @@ clutter_clone_paint (ClutterActor *actor,
if (clutter_actor_is_realized (priv->clone_source)) if (clutter_actor_is_realized (priv->clone_source))
{ {
_clutter_actor_push_clone_paint (); _clutter_actor_push_clone_paint ();
clutter_actor_paint (priv->clone_source, paint_context); clutter_actor_paint (priv->clone_source);
_clutter_actor_pop_clone_paint (); _clutter_actor_pop_clone_paint ();
} }
@@ -194,7 +212,7 @@ clutter_clone_get_paint_volume (ClutterActor *actor,
if (priv->clone_source == NULL) if (priv->clone_source == NULL)
return TRUE; return TRUE;
/* query the volume of the source actor and simply masquerade it as /* query the volume of the source actor and simply masquarade it as
* the clones volume... */ * the clones volume... */
source_volume = clutter_actor_get_paint_volume (priv->clone_source); source_volume = clutter_actor_get_paint_volume (priv->clone_source);
if (source_volume == NULL) if (source_volume == NULL)
@@ -221,16 +239,15 @@ clutter_clone_has_overlaps (ClutterActor *actor)
static void static void
clutter_clone_allocate (ClutterActor *self, clutter_clone_allocate (ClutterActor *self,
const ClutterActorBox *box) const ClutterActorBox *box,
ClutterAllocationFlags flags)
{ {
ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv; ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
ClutterActorClass *parent_class; ClutterActorClass *parent_class;
ClutterActorBox source_box;
float x_scale, y_scale;
/* chain up */ /* chain up */
parent_class = CLUTTER_ACTOR_CLASS (clutter_clone_parent_class); parent_class = CLUTTER_ACTOR_CLASS (clutter_clone_parent_class);
parent_class->allocate (self, box); parent_class->allocate (self, box, flags);
if (priv->clone_source == NULL) if (priv->clone_source == NULL)
return; return;
@@ -240,31 +257,7 @@ clutter_clone_allocate (ClutterActor *self,
*/ */
if (clutter_actor_get_parent (priv->clone_source) != NULL && if (clutter_actor_get_parent (priv->clone_source) != NULL &&
!clutter_actor_has_allocation (priv->clone_source)) !clutter_actor_has_allocation (priv->clone_source))
{ clutter_actor_allocate_preferred_size (priv->clone_source, flags);
float x = 0.f;
float y = 0.f;
clutter_actor_get_fixed_position (priv->clone_source, &x, &y);
clutter_actor_allocate_preferred_size (priv->clone_source, x, y);
}
clutter_actor_get_allocation_box (priv->clone_source, &source_box);
/* We need to scale what the clone-source actor paints to fill our own
* allocation...
*/
x_scale = clutter_actor_box_get_width (box)
/ clutter_actor_box_get_width (&source_box);
y_scale = clutter_actor_box_get_height (box)
/ clutter_actor_box_get_height (&source_box);
if (!G_APPROX_VALUE (priv->x_scale, x_scale, FLT_EPSILON) ||
!G_APPROX_VALUE (priv->y_scale, y_scale, FLT_EPSILON))
{
priv->x_scale = x_scale;
priv->y_scale = y_scale;
clutter_actor_invalidate_transform (CLUTTER_ACTOR (self));
}
#if 0 #if 0
/* XXX - this is wrong: ClutterClone cannot clone unparented /* XXX - this is wrong: ClutterClone cannot clone unparented
@@ -279,7 +272,7 @@ clutter_clone_allocate (ClutterActor *self,
* paint cycle, we can safely give it as much size as it requires * paint cycle, we can safely give it as much size as it requires
*/ */
if (clutter_actor_get_parent (priv->clone_source) == NULL) if (clutter_actor_get_parent (priv->clone_source) == NULL)
clutter_actor_allocate_preferred_size (priv->clone_source); clutter_actor_allocate_preferred_size (priv->clone_source, flags);
#endif #endif
} }
@@ -353,6 +346,8 @@ clutter_clone_class_init (ClutterCloneClass *klass)
* ClutterClone:source: * ClutterClone:source:
* *
* This property specifies the source actor being cloned. * This property specifies the source actor being cloned.
*
* Since: 1.0
*/ */
obj_props[PROP_SOURCE] = obj_props[PROP_SOURCE] =
g_param_spec_object ("source", g_param_spec_object ("source",
@@ -369,9 +364,6 @@ static void
clutter_clone_init (ClutterClone *self) clutter_clone_init (ClutterClone *self)
{ {
self->priv = clutter_clone_get_instance_private (self); self->priv = clutter_clone_get_instance_private (self);
self->priv->x_scale = 1.f;
self->priv->y_scale = 1.f;
} }
/** /**
@@ -381,6 +373,8 @@ clutter_clone_init (ClutterClone *self)
* Creates a new #ClutterActor which clones @source/ * Creates a new #ClutterActor which clones @source/
* *
* Return value: the newly created #ClutterClone * Return value: the newly created #ClutterClone
*
* Since: 1.0
*/ */
ClutterActor * ClutterActor *
clutter_clone_new (ClutterActor *source) clutter_clone_new (ClutterActor *source)
@@ -406,7 +400,8 @@ clutter_clone_set_source_internal (ClutterClone *self,
if (priv->clone_source != NULL) if (priv->clone_source != NULL)
{ {
g_clear_signal_handler (&priv->source_destroy_id, priv->clone_source); g_signal_handler_disconnect (priv->clone_source, priv->source_destroy_id);
priv->source_destroy_id = 0;
_clutter_actor_detach_clone (priv->clone_source, CLUTTER_ACTOR (self)); _clutter_actor_detach_clone (priv->clone_source, CLUTTER_ACTOR (self));
g_object_unref (priv->clone_source); g_object_unref (priv->clone_source);
priv->clone_source = NULL; priv->clone_source = NULL;
@@ -431,6 +426,8 @@ clutter_clone_set_source_internal (ClutterClone *self,
* @source: (allow-none): a #ClutterActor, or %NULL * @source: (allow-none): a #ClutterActor, or %NULL
* *
* Sets @source as the source actor to be cloned by @self. * Sets @source as the source actor to be cloned by @self.
*
* Since: 1.0
*/ */
void void
clutter_clone_set_source (ClutterClone *self, clutter_clone_set_source (ClutterClone *self,
@@ -450,6 +447,8 @@ clutter_clone_set_source (ClutterClone *self,
* Retrieves the source #ClutterActor being cloned by @self. * Retrieves the source #ClutterActor being cloned by @self.
* *
* Return value: (transfer none): the actor source for the clone * Return value: (transfer none): the actor source for the clone
*
* Since: 1.0
*/ */
ClutterActor * ClutterActor *
clutter_clone_get_source (ClutterClone *self) clutter_clone_get_source (ClutterClone *self)

View File

@@ -43,6 +43,14 @@ typedef struct _ClutterClone ClutterClone;
typedef struct _ClutterCloneClass ClutterCloneClass; typedef struct _ClutterCloneClass ClutterCloneClass;
typedef struct _ClutterClonePrivate ClutterClonePrivate; typedef struct _ClutterClonePrivate ClutterClonePrivate;
/**
* ClutterClone:
*
* The #ClutterClone structure contains only private data
* and should be accessed using the provided API
*
* Since: 1.0
*/
struct _ClutterClone struct _ClutterClone
{ {
/*< private >*/ /*< private >*/
@@ -55,6 +63,8 @@ struct _ClutterClone
* ClutterCloneClass: * ClutterCloneClass:
* *
* The #ClutterCloneClass structure contains only private data * The #ClutterCloneClass structure contains only private data
*
* Since: 1.0
*/ */
struct _ClutterCloneClass struct _ClutterCloneClass
{ {

View File

@@ -1,182 +0,0 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2022 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Naveen Kumar <naveen1.kumar@intel.com>
*/
/**
* ClutterColorState:
*
* Color state of each ClutterActor
*
* The #ClutterColorState class contains the colorspace of each color
* states (e.g. sRGB colorspace).
*
* Each [class@Actor] would own such an object.
*
* A single #ClutterColorState object can be shared by multiple [class@Actor]
* or maybe a separate color state for each [class@Actor] (depending on whether
* #ClutterColorState would be statefull or stateless).
*
* #ClutterColorState, if not set during construction, it will default to sRGB
* color state
*
* The #ClutterColorState would have API to get the colorspace, whether the
* actor content is in pq or not, and things like that
*/
#include "clutter-build-config.h"
#include "clutter-color-state.h"
#include "clutter-debug.h"
#include "clutter-enum-types.h"
#include "clutter-private.h"
enum
{
PROP_0,
PROP_COLORSPACE,
N_PROPS
};
static GParamSpec *obj_props[N_PROPS];
typedef struct _ClutterColorStatePrivate ClutterColorStatePrivate;
struct _ClutterColorState
{
GObject parent_instance;
};
struct _ClutterColorStatePrivate
{
ClutterColorspace colorspace;
};
G_DEFINE_TYPE_WITH_PRIVATE (ClutterColorState,
clutter_color_state,
G_TYPE_OBJECT)
ClutterColorspace
clutter_color_state_get_colorspace (ClutterColorState *color_state)
{
ClutterColorStatePrivate *priv;
g_return_val_if_fail (CLUTTER_IS_COLOR_STATE (color_state),
CLUTTER_COLORSPACE_UNKNOWN);
priv = clutter_color_state_get_instance_private (color_state);
return priv->colorspace;
}
static void
clutter_color_state_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterColorState *color_state = CLUTTER_COLOR_STATE (object);
ClutterColorStatePrivate *priv;
priv = clutter_color_state_get_instance_private (color_state);
switch (prop_id)
{
case PROP_COLORSPACE:
priv->colorspace = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
clutter_color_state_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterColorState *color_state = CLUTTER_COLOR_STATE (object);
switch (prop_id)
{
case PROP_COLORSPACE:
g_value_set_enum (value,
clutter_color_state_get_colorspace (color_state));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
clutter_color_state_class_init (ClutterColorStateClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->set_property = clutter_color_state_set_property;
gobject_class->get_property = clutter_color_state_get_property;
/**
* ClutterColorState:colorspace:
*
* Colorspace information of the each color state,
* defaults to sRGB colorspace
*/
obj_props[PROP_COLORSPACE] =
g_param_spec_enum ("colorspace",
P_("Colorspace"),
P_("Colorspace information of the color state"),
CLUTTER_TYPE_COLORSPACE,
CLUTTER_COLORSPACE_SRGB,
CLUTTER_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (gobject_class, N_PROPS, obj_props);
}
static void
clutter_color_state_init (ClutterColorState *color_state)
{
}
/**
* clutter_color_state_new:
*
* Create a new ClutterColorState object.
*
* Return value: A new ClutterColorState object.
**/
ClutterColorState*
clutter_color_state_new (ClutterColorspace colorspace)
{
return g_object_new (CLUTTER_TYPE_COLOR_STATE,
"colorspace", colorspace,
NULL);
}

View File

@@ -21,6 +21,18 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>. * License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/ */
/**
* SECTION:clutter-color
* @short_description: Color management and manipulation.
*
* #ClutterColor is a simple type for representing colors in Clutter.
*
* A #ClutterColor is expressed as a 4-tuple of values ranging from
* zero to 255, one for each color channel plus one for the alpha.
*
* The alpha channel is fully opaque at 255 and fully transparent at 0.
*/
#include "clutter-build-config.h" #include "clutter-build-config.h"
#include <math.h> #include <math.h>
@@ -98,6 +110,8 @@ static const ClutterColor static_colors[] = {
* *
* Return value: a pointer to a static color; the returned pointer * Return value: a pointer to a static color; the returned pointer
* is owned by Clutter and it should never be modified or freed * is owned by Clutter and it should never be modified or freed
*
* Since: 1.6
*/ */
const ClutterColor * const ClutterColor *
clutter_color_get_static (ClutterStaticColor color) clutter_color_get_static (ClutterStaticColor color)
@@ -597,7 +611,7 @@ parse_hsla (ClutterColor *color,
/** /**
* clutter_color_from_string: * clutter_color_from_string:
* @color: (out caller-allocates): return location for a #ClutterColor * @color: (out caller-allocates): return location for a #ClutterColor
* @str: a string specifying a color * @str: a string specifiying a color
* *
* Parses a string definition of a color, filling the #ClutterColor.red, * Parses a string definition of a color, filling the #ClutterColor.red,
* #ClutterColor.green, #ClutterColor.blue and #ClutterColor.alpha fields * #ClutterColor.green, #ClutterColor.blue and #ClutterColor.alpha fields
@@ -635,6 +649,8 @@ parse_hsla (ClutterColor *color,
* be fully opaque. * be fully opaque.
* *
* Return value: %TRUE if parsing succeeded, and %FALSE otherwise * Return value: %TRUE if parsing succeeded, and %FALSE otherwise
*
* Since: 1.0
*/ */
gboolean gboolean
clutter_color_from_string (ClutterColor *color, clutter_color_from_string (ClutterColor *color,
@@ -767,6 +783,8 @@ clutter_color_from_string (ClutterColor *color,
* respectively. * respectively.
* *
* Return value: (transfer full): a newly-allocated text string * Return value: (transfer full): a newly-allocated text string
*
* Since: 0.2
*/ */
gchar * gchar *
clutter_color_to_string (const ClutterColor *color) clutter_color_to_string (const ClutterColor *color)
@@ -785,12 +803,14 @@ clutter_color_to_string (const ClutterColor *color)
* @v1: (type Clutter.Color): a #ClutterColor * @v1: (type Clutter.Color): a #ClutterColor
* @v2: (type Clutter.Color): a #ClutterColor * @v2: (type Clutter.Color): a #ClutterColor
* *
* Compares two `ClutterColor`s and checks if they are the same. * Compares two #ClutterColor<!-- -->s and checks if they are the same.
* *
* This function can be passed to g_hash_table_new() as the @key_equal_func * This function can be passed to g_hash_table_new() as the @key_equal_func
* parameter, when using `ClutterColor`s as keys in a #GHashTable. * parameter, when using #ClutterColor<!-- -->s as keys in a #GHashTable.
* *
* Return value: %TRUE if the two colors are the same. * Return value: %TRUE if the two colors are the same.
*
* Since: 0.2
*/ */
gboolean gboolean
clutter_color_equal (gconstpointer v1, clutter_color_equal (gconstpointer v1,
@@ -820,9 +840,11 @@ clutter_color_equal (gconstpointer v1,
* Converts a #ClutterColor to a hash value. * Converts a #ClutterColor to a hash value.
* *
* This function can be passed to g_hash_table_new() as the @hash_func * This function can be passed to g_hash_table_new() as the @hash_func
* parameter, when using `ClutterColor`s as keys in a #GHashTable. * parameter, when using #ClutterColor<!-- -->s as keys in a #GHashTable.
* *
* Return value: a hash value corresponding to the color * Return value: a hash value corresponding to the color
*
* Since: 1.0
*/ */
guint guint
clutter_color_hash (gconstpointer v) clutter_color_hash (gconstpointer v)
@@ -837,8 +859,10 @@ clutter_color_hash (gconstpointer v)
* @progress: the interpolation progress * @progress: the interpolation progress
* @result: (out): return location for the interpolation * @result: (out): return location for the interpolation
* *
* Interpolates between @initial and @final `ClutterColor`s * Interpolates between @initial and @final #ClutterColor<!-- -->s
* using @progress * using @progress
*
* Since: 1.6
*/ */
void void
clutter_color_interpolate (const ClutterColor *initial, clutter_color_interpolate (const ClutterColor *initial,
@@ -880,12 +904,14 @@ clutter_color_progress (const GValue *a,
* freed using clutter_color_free(). * freed using clutter_color_free().
* *
* Return value: (transfer full): an allocated copy of @color. * Return value: (transfer full): an allocated copy of @color.
*
* Since: 0.2
*/ */
ClutterColor * ClutterColor *
clutter_color_copy (const ClutterColor *color) clutter_color_copy (const ClutterColor *color)
{ {
if (G_LIKELY (color != NULL)) if (G_LIKELY (color != NULL))
return g_memdup2 (color, sizeof (ClutterColor)); return g_slice_dup (ClutterColor, color);
return NULL; return NULL;
} }
@@ -895,12 +921,14 @@ clutter_color_copy (const ClutterColor *color)
* @color: a #ClutterColor * @color: a #ClutterColor
* *
* Frees a color structure created with clutter_color_copy(). * Frees a color structure created with clutter_color_copy().
*
* Since: 0.2
*/ */
void void
clutter_color_free (ClutterColor *color) clutter_color_free (ClutterColor *color)
{ {
if (G_LIKELY (color != NULL)) if (G_LIKELY (color != NULL))
g_free (color); g_slice_free (ClutterColor, color);
} }
/** /**
@@ -914,12 +942,14 @@ clutter_color_free (ClutterColor *color)
* *
* This function is the equivalent of: * This function is the equivalent of:
* *
* ```c * |[
* clutter_color_init (clutter_color_alloc (), red, green, blue, alpha); * clutter_color_init (clutter_color_alloc (), red, green, blue, alpha);
* ``` * ]|
* *
* Return value: (transfer full): the newly allocated color. * Return value: (transfer full): the newly allocated color.
* Use clutter_color_free() when done * Use clutter_color_free() when done
*
* Since: 0.8
*/ */
ClutterColor * ClutterColor *
clutter_color_new (guint8 red, clutter_color_new (guint8 red,
@@ -941,11 +971,13 @@ clutter_color_new (guint8 red,
* *
* Return value: (transfer full): the newly allocated #ClutterColor; use * Return value: (transfer full): the newly allocated #ClutterColor; use
* clutter_color_free() to free its resources * clutter_color_free() to free its resources
*
* Since: 1.12
*/ */
ClutterColor * ClutterColor *
clutter_color_alloc (void) clutter_color_alloc (void)
{ {
return g_new0 (ClutterColor, 1); return g_slice_new0 (ClutterColor);
} }
/** /**
@@ -959,6 +991,8 @@ clutter_color_alloc (void)
* Initializes @color with the given values. * Initializes @color with the given values.
* *
* Return value: (transfer none): the initialized #ClutterColor * Return value: (transfer none): the initialized #ClutterColor
*
* Since: 1.12
*/ */
ClutterColor * ClutterColor *
clutter_color_init (ClutterColor *color, clutter_color_init (ClutterColor *color,
@@ -1024,6 +1058,8 @@ G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterColor, clutter_color,
* @color: the color to set * @color: the color to set
* *
* Sets @value to @color. * Sets @value to @color.
*
* Since: 0.8
*/ */
void void
clutter_value_set_color (GValue *value, clutter_value_set_color (GValue *value,
@@ -1041,6 +1077,8 @@ clutter_value_set_color (GValue *value,
* Gets the #ClutterColor contained in @value. * Gets the #ClutterColor contained in @value.
* *
* Return value: (transfer none): the color inside the passed #GValue * Return value: (transfer none): the color inside the passed #GValue
*
* Since: 0.8
*/ */
const ClutterColor * const ClutterColor *
clutter_value_get_color (const GValue *value) clutter_value_get_color (const GValue *value)
@@ -1134,6 +1172,8 @@ clutter_param_color_get_type (void)
* Creates a #GParamSpec for properties using #ClutterColor. * Creates a #GParamSpec for properties using #ClutterColor.
* *
* Return value: the newly created #GParamSpec * Return value: the newly created #GParamSpec
*
* Since: 0.8
*/ */
GParamSpec * GParamSpec *
clutter_param_spec_color (const gchar *name, clutter_param_spec_color (const gchar *name,

View File

@@ -43,12 +43,7 @@ G_BEGIN_DECLS
* @blue: blue component, between 0 and 255 * @blue: blue component, between 0 and 255
* @alpha: alpha component, between 0 and 255 * @alpha: alpha component, between 0 and 255
* *
* A simple type for representing colors. * Color representation.
*
* A #ClutterColor is expressed as a 4-tuple of values ranging from
* zero to 255, one for each color channel plus one for the alpha.
*
* The alpha channel is fully opaque at 255 and fully transparent at 0.
*/ */
struct _ClutterColor struct _ClutterColor
{ {
@@ -68,6 +63,8 @@ struct _ClutterColor
* @a: value for the alpha channel, between 0 and 255 * @a: value for the alpha channel, between 0 and 255
* *
* A macro that initializes a #ClutterColor, to be used when declaring it. * A macro that initializes a #ClutterColor, to be used when declaring it.
*
* Since: 1.12
*/ */
#define CLUTTER_COLOR_INIT(r,g,b,a) { (r), (g), (b), (a) } #define CLUTTER_COLOR_INIT(r,g,b,a) { (r), (g), (b), (a) }
@@ -154,7 +151,9 @@ void clutter_color_interpolate (const ClutterColor *initial,
* CLUTTER_VALUE_HOLDS_COLOR: * CLUTTER_VALUE_HOLDS_COLOR:
* @x: a #GValue * @x: a #GValue
* *
* Evaluates to %TRUE if @x holds a `ClutterColor`. * Evaluates to %TRUE if @x holds a #ClutterColor<!-- -->.
*
* Since: 1.0
*/ */
#define CLUTTER_VALUE_HOLDS_COLOR(x) (G_VALUE_HOLDS ((x), CLUTTER_TYPE_COLOR)) #define CLUTTER_VALUE_HOLDS_COLOR(x) (G_VALUE_HOLDS ((x), CLUTTER_TYPE_COLOR))
@@ -166,6 +165,8 @@ typedef struct _ClutterParamSpecColor ClutterParamSpecColor;
* *
* A #GParamSpec subclass for defining properties holding * A #GParamSpec subclass for defining properties holding
* a #ClutterColor. * a #ClutterColor.
*
* Since: 1.0
*/ */
struct _ClutterParamSpecColor struct _ClutterParamSpecColor
{ {

View File

@@ -23,12 +23,14 @@
*/ */
/** /**
* ClutterColorizeEffect: * SECTION:clutter-colorize-effect
* * @short_description: A colorization effect
* A colorization effect * @see_also: #ClutterEffect, #ClutterOffscreenEffect
* *
* #ClutterColorizeEffect is a sub-class of #ClutterEffect that * #ClutterColorizeEffect is a sub-class of #ClutterEffect that
* colorizes an actor with the given tint. * colorizes an actor with the given tint.
*
* #ClutterColorizeEffect is available since Clutter 1.4
*/ */
#define CLUTTER_COLORIZE_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_COLORIZE_EFFECT, ClutterColorizeEffectClass)) #define CLUTTER_COLORIZE_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_COLORIZE_EFFECT, ClutterColorizeEffectClass))
@@ -37,6 +39,8 @@
#include "clutter-build-config.h" #include "clutter-build-config.h"
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-colorize-effect.h" #include "clutter-colorize-effect.h"
#include "cogl/cogl.h" #include "cogl/cogl.h"
@@ -55,6 +59,9 @@ struct _ClutterColorizeEffect
gint tint_uniform; gint tint_uniform;
gint tex_width;
gint tex_height;
CoglPipeline *pipeline; CoglPipeline *pipeline;
}; };
@@ -97,15 +104,67 @@ G_DEFINE_TYPE (ClutterColorizeEffect,
clutter_colorize_effect, clutter_colorize_effect,
CLUTTER_TYPE_OFFSCREEN_EFFECT); CLUTTER_TYPE_OFFSCREEN_EFFECT);
static CoglPipeline * static gboolean
clutter_colorize_effect_create_pipeline (ClutterOffscreenEffect *effect, clutter_colorize_effect_pre_paint (ClutterEffect *effect)
CoglTexture *texture)
{ {
ClutterColorizeEffect *colorize_effect = CLUTTER_COLORIZE_EFFECT (effect); ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect);
ClutterEffectClass *parent_class;
cogl_pipeline_set_layer_texture (colorize_effect->pipeline, 0, texture); if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
return FALSE;
return cogl_object_ref (colorize_effect->pipeline); if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
{
/* if we don't have support for GLSL shaders then we
* forcibly disable the ActorMeta
*/
g_warning ("Unable to use the ShaderEffect: the graphics hardware "
"or the current GL driver does not implement support "
"for the GLSL shading language.");
clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE);
return FALSE;
}
parent_class = CLUTTER_EFFECT_CLASS (clutter_colorize_effect_parent_class);
if (parent_class->pre_paint (effect))
{
ClutterOffscreenEffect *offscreen_effect =
CLUTTER_OFFSCREEN_EFFECT (effect);
CoglHandle texture;
texture = clutter_offscreen_effect_get_texture (offscreen_effect);
self->tex_width = cogl_texture_get_width (texture);
self->tex_height = cogl_texture_get_height (texture);
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
return TRUE;
}
else
return FALSE;
}
static void
clutter_colorize_effect_paint_target (ClutterOffscreenEffect *effect)
{
ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect);
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
ClutterActor *actor;
guint8 paint_opacity;
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
paint_opacity = clutter_actor_get_paint_opacity (actor);
cogl_pipeline_set_color4ub (self->pipeline,
paint_opacity,
paint_opacity,
paint_opacity,
paint_opacity);
cogl_framebuffer_draw_rectangle (framebuffer,
self->pipeline,
0, 0,
self->tex_width, self->tex_height);
} }
static void static void
@@ -166,11 +225,14 @@ clutter_colorize_effect_get_property (GObject *gobject,
static void static void
clutter_colorize_effect_class_init (ClutterColorizeEffectClass *klass) clutter_colorize_effect_class_init (ClutterColorizeEffectClass *klass)
{ {
ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterOffscreenEffectClass *offscreen_class; ClutterOffscreenEffectClass *offscreen_class;
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
offscreen_class->create_pipeline = clutter_colorize_effect_create_pipeline; offscreen_class->paint_target = clutter_colorize_effect_paint_target;
effect_class->pre_paint = clutter_colorize_effect_pre_paint;
gobject_class->set_property = clutter_colorize_effect_set_property; gobject_class->set_property = clutter_colorize_effect_set_property;
gobject_class->get_property = clutter_colorize_effect_get_property; gobject_class->get_property = clutter_colorize_effect_get_property;
@@ -180,6 +242,8 @@ clutter_colorize_effect_class_init (ClutterColorizeEffectClass *klass)
* ClutterColorizeEffect:tint: * ClutterColorizeEffect:tint:
* *
* The tint to apply to the actor * The tint to apply to the actor
*
* Since: 1.4
*/ */
obj_props[PROP_TINT] = obj_props[PROP_TINT] =
clutter_param_spec_color ("tint", clutter_param_spec_color ("tint",
@@ -250,6 +314,8 @@ clutter_colorize_effect_init (ClutterColorizeEffect *self)
* clutter_actor_add_effect() * clutter_actor_add_effect()
* *
* Return value: the newly created #ClutterColorizeEffect or %NULL * Return value: the newly created #ClutterColorizeEffect or %NULL
*
* Since: 1.4
*/ */
ClutterEffect * ClutterEffect *
clutter_colorize_effect_new (const ClutterColor *tint) clutter_colorize_effect_new (const ClutterColor *tint)
@@ -265,6 +331,8 @@ clutter_colorize_effect_new (const ClutterColor *tint)
* @tint: the color to be used * @tint: the color to be used
* *
* Sets the tint to be used when colorizing * Sets the tint to be used when colorizing
*
* Since: 1.4
*/ */
void void
clutter_colorize_effect_set_tint (ClutterColorizeEffect *effect, clutter_colorize_effect_set_tint (ClutterColorizeEffect *effect,
@@ -287,6 +355,8 @@ clutter_colorize_effect_set_tint (ClutterColorizeEffect *effect,
* @tint: (out caller-allocates): return location for the color used * @tint: (out caller-allocates): return location for the color used
* *
* Retrieves the tint used by @effect * Retrieves the tint used by @effect
*
* Since: 1.4
*/ */
void void
clutter_colorize_effect_get_tint (ClutterColorizeEffect *effect, clutter_colorize_effect_get_tint (ClutterColorizeEffect *effect,

View File

@@ -38,6 +38,14 @@ G_BEGIN_DECLS
#define CLUTTER_COLORIZE_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_COLORIZE_EFFECT, ClutterColorizeEffect)) #define CLUTTER_COLORIZE_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_COLORIZE_EFFECT, ClutterColorizeEffect))
#define CLUTTER_IS_COLORIZE_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_COLORIZE_EFFECT)) #define CLUTTER_IS_COLORIZE_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_COLORIZE_EFFECT))
/**
* ClutterColorizeEffect:
*
* #ClutterColorizeEffect is an opaque structure
* whose members cannot be directly accessed
*
* Since: 1.4
*/
typedef struct _ClutterColorizeEffect ClutterColorizeEffect; typedef struct _ClutterColorizeEffect ClutterColorizeEffect;
typedef struct _ClutterColorizeEffectClass ClutterColorizeEffectClass; typedef struct _ClutterColorizeEffectClass ClutterColorizeEffectClass;

View File

@@ -0,0 +1,16 @@
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_CONFIG_H__
#define __CLUTTER_CONFIG_H__
#include <glib.h>
G_BEGIN_DECLS
@CLUTTER_CONFIG_DEFINES@
G_END_DECLS
#endif /* __CLUTTER_CONFIG_H__ */

View File

@@ -30,6 +30,13 @@ gboolean clutter_constraint_update_allocation (ClutterConstraint *constraint,
ClutterActor *actor, ClutterActor *actor,
ClutterActorBox *allocation); ClutterActorBox *allocation);
void clutter_constraint_update_preferred_size (ClutterConstraint *constraint,
ClutterActor *actor,
ClutterOrientation direction,
float for_size,
float *minimum_size,
float *natural_size);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_CONSTRAINT_PRIVATE_H__ */ #endif /* __CLUTTER_CONSTRAINT_PRIVATE_H__ */

View File

@@ -23,9 +23,10 @@
*/ */
/** /**
* ClutterConstraint: * SECTION:clutter-constraint
* * @Title: ClutterConstraint
* Abstract class for constraints on position or size * @Short_Description: Abstract class for constraints on position or size
* @See_Also: #ClutterAction
* *
* #ClutterConstraint is a base abstract class for modifiers of a #ClutterActor * #ClutterConstraint is a base abstract class for modifiers of a #ClutterActor
* position or size. * position or size.
@@ -36,6 +37,8 @@
* allocation of the actor to which they are applied by overriding the * allocation of the actor to which they are applied by overriding the
* #ClutterConstraintClass.update_allocation() virtual function. * #ClutterConstraintClass.update_allocation() virtual function.
* *
* #ClutterConstraint is available since Clutter 1.4
*
* ## Using Constraints * ## Using Constraints
* *
* Constraints can be used with fixed layout managers, like * Constraints can be used with fixed layout managers, like
@@ -45,7 +48,7 @@
* Constraints provide a way to build user interfaces by using * Constraints provide a way to build user interfaces by using
* relations between #ClutterActors, without explicit fixed * relations between #ClutterActors, without explicit fixed
* positioning and sizing, similarly to how fluid layout managers like * positioning and sizing, similarly to how fluid layout managers like
* #ClutterBoxLayout lay out their children. * #ClutterBoxLayout and #ClutterTableLayout lay out their children.
* *
* Constraints are attached to a #ClutterActor, and are available * Constraints are attached to a #ClutterActor, and are available
* for inspection using clutter_actor_get_constraints(). * for inspection using clutter_actor_get_constraints().
@@ -157,26 +160,28 @@ constraint_update_preferred_size (ClutterConstraint *constraint,
} }
static void static void
clutter_constraint_set_enabled (ClutterActorMeta *meta, clutter_constraint_notify (GObject *gobject,
gboolean is_enabled) GParamSpec *pspec)
{ {
ClutterActorMetaClass *parent_class = if (strcmp (pspec->name, "enabled") == 0)
CLUTTER_ACTOR_META_CLASS (clutter_constraint_parent_class); {
ClutterActor *actor; ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject);
ClutterActor *actor = clutter_actor_meta_get_actor (meta);
actor = clutter_actor_meta_get_actor (meta); if (actor != NULL)
if (actor)
clutter_actor_queue_relayout (actor); clutter_actor_queue_relayout (actor);
}
parent_class->set_enabled (meta, is_enabled); if (G_OBJECT_CLASS (clutter_constraint_parent_class)->notify != NULL)
G_OBJECT_CLASS (clutter_constraint_parent_class)->notify (gobject, pspec);
} }
static void static void
clutter_constraint_class_init (ClutterConstraintClass *klass) clutter_constraint_class_init (ClutterConstraintClass *klass)
{ {
ClutterActorMetaClass *actor_meta_class = CLUTTER_ACTOR_META_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
actor_meta_class->set_enabled = clutter_constraint_set_enabled; gobject_class->notify = clutter_constraint_notify;
klass->update_allocation = constraint_update_allocation; klass->update_allocation = constraint_update_allocation;
klass->update_preferred_size = constraint_update_preferred_size; klass->update_preferred_size = constraint_update_preferred_size;
@@ -217,17 +222,6 @@ clutter_constraint_update_allocation (ClutterConstraint *constraint,
return !clutter_actor_box_equal (allocation, &old_alloc); 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 void
clutter_constraint_update_preferred_size (ClutterConstraint *constraint, clutter_constraint_update_preferred_size (ClutterConstraint *constraint,
ClutterActor *actor, ClutterActor *actor,

View File

@@ -42,6 +42,14 @@ G_BEGIN_DECLS
typedef struct _ClutterConstraintClass ClutterConstraintClass; typedef struct _ClutterConstraintClass ClutterConstraintClass;
/**
* ClutterConstraint:
*
* The #ClutterConstraint structure contains only
* private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _ClutterConstraint struct _ClutterConstraint
{ {
/*< private >*/ /*< private >*/
@@ -58,6 +66,8 @@ struct _ClutterConstraint
* *
* The #ClutterConstraintClass structure contains * The #ClutterConstraintClass structure contains
* only private data * only private data
*
* Since: 1.4
*/ */
struct _ClutterConstraintClass struct _ClutterConstraintClass
{ {
@@ -89,14 +99,6 @@ struct _ClutterConstraintClass
CLUTTER_EXPORT CLUTTER_EXPORT
GType clutter_constraint_get_type (void) G_GNUC_CONST; GType clutter_constraint_get_type (void) G_GNUC_CONST;
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 */ /* ClutterActor API */
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_actor_add_constraint (ClutterActor *self, void clutter_actor_add_constraint (ClutterActor *self,

View File

@@ -37,7 +37,6 @@
#include "clutter-actor-private.h" #include "clutter-actor-private.h"
#include "clutter-child-meta.h" #include "clutter-child-meta.h"
#include "clutter-container-private.h"
#include "clutter-debug.h" #include "clutter-debug.h"
#include "clutter-main.h" #include "clutter-main.h"
#include "clutter-marshal.h" #include "clutter-marshal.h"
@@ -63,14 +62,20 @@
} G_STMT_END } G_STMT_END
/** /**
* ClutterContainer: * SECTION:clutter-container
* @short_description: An interface for container actors
* *
* An interface for container actors * #ClutterContainer is an interface implemented by #ClutterActor, and
*
* #ClutterContainer is an interface implemented by [class@Actor], and
* it provides some common API for notifying when a child actor is added * it provides some common API for notifying when a child actor is added
* or removed, as well as the infrastructure for accessing child properties * or removed, as well as the infrastructure for accessing child properties
* through [class@ChildMeta]. * through #ClutterChildMeta.
*
* Until Clutter 1.10, the #ClutterContainer interface was also the public
* API for implementing container actors; this part of the interface has
* been deprecated: #ClutterContainer has a default implementation which
* defers to #ClutterActor the child addition and removal, as well as the
* iteration. See the documentation of #ClutterContainerIface for the list
* of virtual functions that should be overridden.
*/ */
enum enum
@@ -113,6 +118,62 @@ container_real_remove (ClutterContainer *container,
clutter_actor_remove_child (CLUTTER_ACTOR (container), actor); clutter_actor_remove_child (CLUTTER_ACTOR (container), actor);
} }
typedef struct {
ClutterCallback callback;
gpointer data;
} ForeachClosure;
static gboolean
foreach_cb (ClutterActor *actor,
gpointer data)
{
ForeachClosure *clos = data;
clos->callback (actor, clos->data);
return TRUE;
}
static void
container_real_foreach (ClutterContainer *container,
ClutterCallback callback,
gpointer user_data)
{
ForeachClosure clos;
clos.callback = callback;
clos.data = user_data;
_clutter_actor_foreach_child (CLUTTER_ACTOR (container),
foreach_cb,
&clos);
}
static void
container_real_raise (ClutterContainer *container,
ClutterActor *child,
ClutterActor *sibling)
{
ClutterActor *self = CLUTTER_ACTOR (container);
clutter_actor_set_child_above_sibling (self, child, sibling);
}
static void
container_real_lower (ClutterContainer *container,
ClutterActor *child,
ClutterActor *sibling)
{
ClutterActor *self = CLUTTER_ACTOR (container);
clutter_actor_set_child_below_sibling (self, child, sibling);
}
static void
container_real_sort_depth_order (ClutterContainer *container)
{
}
static void static void
clutter_container_default_init (ClutterContainerInterface *iface) clutter_container_default_init (ClutterContainerInterface *iface)
{ {
@@ -126,8 +187,10 @@ clutter_container_default_init (ClutterContainerInterface *iface)
* @container: the actor which received the signal * @container: the actor which received the signal
* @actor: the new child that has been added to @container * @actor: the new child that has been added to @container
* *
* The signal is emitted each time an actor * The ::actor-added signal is emitted each time an actor
* has been added to @container. * has been added to @container.
*
* Since: 0.4
*/ */
container_signals[ACTOR_ADDED] = container_signals[ACTOR_ADDED] =
g_signal_new (I_("actor-added"), g_signal_new (I_("actor-added"),
@@ -142,8 +205,10 @@ clutter_container_default_init (ClutterContainerInterface *iface)
* @container: the actor which received the signal * @container: the actor which received the signal
* @actor: the child that has been removed from @container * @actor: the child that has been removed from @container
* *
* The signal is emitted each time an actor * The ::actor-removed signal is emitted each time an actor
* is removed from @container. * is removed from @container.
*
* Since: 0.4
*/ */
container_signals[ACTOR_REMOVED] = container_signals[ACTOR_REMOVED] =
g_signal_new (I_("actor-removed"), g_signal_new (I_("actor-removed"),
@@ -160,9 +225,11 @@ clutter_container_default_init (ClutterContainerInterface *iface)
* @actor: the child that has had a property set * @actor: the child that has had a property set
* @pspec: (type GParamSpec): the #GParamSpec of the property set * @pspec: (type GParamSpec): the #GParamSpec of the property set
* *
* The signal is emitted each time a property is * The ::child-notify signal is emitted each time a property is
* being set through the clutter_container_child_set() and * being set through the clutter_container_child_set() and
* clutter_container_child_set_property() calls. * clutter_container_child_set_property() calls.
*
* Since: 0.8
*/ */
container_signals[CHILD_NOTIFY] = container_signals[CHILD_NOTIFY] =
g_signal_new (I_("child-notify"), g_signal_new (I_("child-notify"),
@@ -176,6 +243,10 @@ clutter_container_default_init (ClutterContainerInterface *iface)
iface->add = container_real_add; iface->add = container_real_add;
iface->remove = container_real_remove; iface->remove = container_real_remove;
iface->foreach = container_real_foreach;
iface->raise = container_real_raise;
iface->lower = container_real_lower;
iface->sort_depth_order = container_real_sort_depth_order;
iface->child_meta_type = G_TYPE_INVALID; iface->child_meta_type = G_TYPE_INVALID;
iface->create_child_meta = create_child_meta; iface->create_child_meta = create_child_meta;
@@ -289,7 +360,7 @@ container_remove_valist (ClutterContainer *container,
* @first_actor: the first #ClutterActor to add * @first_actor: the first #ClutterActor to add
* @...: %NULL terminated list of actors to add * @...: %NULL terminated list of actors to add
* *
* Adds a list of `ClutterActor`s to @container. Each time and * Adds a list of #ClutterActor<!-- -->s to @container. Each time and
* actor is added, the "actor-added" signal is emitted. Each actor should * actor is added, the "actor-added" signal is emitted. Each actor should
* be parented to @container, which takes a reference on the actor. You * be parented to @container, which takes a reference on the actor. You
* cannot add a #ClutterActor to more than one #ClutterContainer. * cannot add a #ClutterActor to more than one #ClutterContainer.
@@ -298,6 +369,8 @@ container_remove_valist (ClutterContainer *container,
* deprecated virtual function. The default implementation will * deprecated virtual function. The default implementation will
* call clutter_actor_add_child(). * call clutter_actor_add_child().
* *
* Since: 0.4
*
* Deprecated: 1.10: Use clutter_actor_add_child() instead. * Deprecated: 1.10: Use clutter_actor_add_child() instead.
*/ */
void void
@@ -329,6 +402,8 @@ clutter_container_add (ClutterContainer *container,
* deprecated virtual function. The default implementation will * deprecated virtual function. The default implementation will
* call clutter_actor_add_child(). * call clutter_actor_add_child().
* *
* Since: 0.4
*
* Deprecated: 1.10: Use clutter_actor_add_child() instead. * Deprecated: 1.10: Use clutter_actor_add_child() instead.
*/ */
void void
@@ -341,13 +416,40 @@ clutter_container_add_actor (ClutterContainer *container,
container_add_actor (container, actor); container_add_actor (container, actor);
} }
/**
* clutter_container_add_valist: (skip)
* @container: a #ClutterContainer
* @first_actor: the first #ClutterActor to add
* @var_args: list of actors to add, followed by %NULL
*
* Alternative va_list version of clutter_container_add().
*
* This function will call #ClutterContainerIface.add(), which is a
* deprecated virtual function. The default implementation will
* call clutter_actor_add_child().
*
* Since: 0.4
*
* Deprecated: 1.10: Use clutter_actor_add_child() instead.
*/
void
clutter_container_add_valist (ClutterContainer *container,
ClutterActor *first_actor,
va_list var_args)
{
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
g_return_if_fail (CLUTTER_IS_ACTOR (first_actor));
container_add_valist (container, first_actor, var_args);
}
/** /**
* clutter_container_remove: (skip) * clutter_container_remove: (skip)
* @container: a #ClutterContainer * @container: a #ClutterContainer
* @first_actor: first #ClutterActor to remove * @first_actor: first #ClutterActor to remove
* @...: a %NULL-terminated list of actors to remove * @...: a %NULL-terminated list of actors to remove
* *
* Removes a %NULL terminated list of `ClutterActor`s from * Removes a %NULL terminated list of #ClutterActor<!-- -->s from
* @container. Each actor should be unparented, so if you want to keep it * @container. Each actor should be unparented, so if you want to keep it
* around you must hold a reference to it yourself, using g_object_ref(). * around you must hold a reference to it yourself, using g_object_ref().
* Each time an actor is removed, the "actor-removed" signal is * Each time an actor is removed, the "actor-removed" signal is
@@ -357,6 +459,8 @@ clutter_container_add_actor (ClutterContainer *container,
* deprecated virtual function. The default implementation will call * deprecated virtual function. The default implementation will call
* clutter_actor_remove_child(). * clutter_actor_remove_child().
* *
* Since: 0.4
*
* Deprecated: 1.10: Use clutter_actor_remove_child() instead. * Deprecated: 1.10: Use clutter_actor_remove_child() instead.
*/ */
void void
@@ -388,6 +492,8 @@ clutter_container_remove (ClutterContainer *container,
* deprecated virtual function. The default implementation will call * deprecated virtual function. The default implementation will call
* clutter_actor_remove_child(). * clutter_actor_remove_child().
* *
* Since: 0.4
*
* Deprecated: 1.10: Use clutter_actor_remove_child() instead. * Deprecated: 1.10: Use clutter_actor_remove_child() instead.
*/ */
void void
@@ -400,6 +506,337 @@ clutter_container_remove_actor (ClutterContainer *container,
container_remove_actor (container, actor); container_remove_actor (container, actor);
} }
/**
* clutter_container_remove_valist: (skip)
* @container: a #ClutterContainer
* @first_actor: the first #ClutterActor to add
* @var_args: list of actors to remove, followed by %NULL
*
* Alternative va_list version of clutter_container_remove().
*
* This function will call #ClutterContainerIface.remove(), which is a
* deprecated virtual function. The default implementation will call
* clutter_actor_remove_child().
*
* Since: 0.4
*
* Deprecated: 1.10: Use clutter_actor_remove_child() instead.
*/
void
clutter_container_remove_valist (ClutterContainer *container,
ClutterActor *first_actor,
va_list var_args)
{
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
g_return_if_fail (CLUTTER_IS_ACTOR (first_actor));
container_remove_valist (container, first_actor, var_args);
}
static void
get_children_cb (ClutterActor *child,
gpointer data)
{
GList **children = data;
*children = g_list_prepend (*children, child);
}
/**
* clutter_container_get_children:
* @container: a #ClutterContainer
*
* Retrieves all the children of @container.
*
* Return value: (element-type Clutter.Actor) (transfer container): a list
* of #ClutterActor<!-- -->s. Use g_list_free() on the returned
* list when done.
*
* Since: 0.4
*
* Deprecated: 1.10: Use clutter_actor_get_children() instead.
*/
GList *
clutter_container_get_children (ClutterContainer *container)
{
GList *retval;
g_return_val_if_fail (CLUTTER_IS_CONTAINER (container), NULL);
retval = NULL;
clutter_container_foreach (container, get_children_cb, &retval);
return g_list_reverse (retval);
}
/**
* clutter_container_foreach:
* @container: a #ClutterContainer
* @callback: (scope call): a function to be called for each child
* @user_data: data to be passed to the function, or %NULL
*
* Calls @callback for each child of @container that was added
* by the application (with clutter_container_add_actor()). Does
* not iterate over "internal" children that are part of the
* container's own implementation, if any.
*
* This function calls the #ClutterContainerIface.foreach()
* virtual function, which has been deprecated.
*
* Since: 0.4
*
* Deprecated: 1.10: Use clutter_actor_get_first_child() or
* clutter_actor_get_last_child() to retrieve the beginning of
* the list of children, and clutter_actor_get_next_sibling()
* and clutter_actor_get_previous_sibling() to iterate over it;
* alternatively, use the #ClutterActorIter API.
*/
void
clutter_container_foreach (ClutterContainer *container,
ClutterCallback callback,
gpointer user_data)
{
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
g_return_if_fail (callback != NULL);
#ifdef CLUTTER_ENABLE_DEBUG
if (G_UNLIKELY (_clutter_diagnostic_enabled ()))
{
ClutterContainerIface *iface = CLUTTER_CONTAINER_GET_IFACE (container);
if (iface->foreach != container_real_foreach)
_clutter_diagnostic_message ("The ClutterContainer::foreach() "
"virtual function has been deprecated "
"and it should not be overridden by "
"newly written code");
}
#endif /* CLUTTER_ENABLE_DEBUG */
CLUTTER_CONTAINER_GET_IFACE (container)->foreach (container,
callback,
user_data);
}
/**
* clutter_container_foreach_with_internals:
* @container: a #ClutterContainer
* @callback: (scope call): a function to be called for each child
* @user_data: data to be passed to the function, or %NULL
*
* Calls @callback for each child of @container, including "internal"
* children built in to the container itself that were never added
* by the application.
*
* This function calls the #ClutterContainerIface.foreach_with_internals()
* virtual function, which has been deprecated.
*
* Since: 1.0
*
* Deprecated: 1.10: See clutter_container_foreach().
*/
void
clutter_container_foreach_with_internals (ClutterContainer *container,
ClutterCallback callback,
gpointer user_data)
{
ClutterContainerIface *iface;
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
g_return_if_fail (callback != NULL);
iface = CLUTTER_CONTAINER_GET_IFACE (container);
#ifdef CLUTTER_ENABLE_DEBUG
if (G_UNLIKELY (_clutter_diagnostic_enabled ()))
{
if (iface->foreach_with_internals != NULL)
_clutter_diagnostic_message ("The ClutterContainer::foreach_with_internals() "
"virtual function has been deprecated "
"and it should not be overridden by "
"newly written code");
}
#endif /* CLUTTER_ENABLE_DEBUG */
if (iface->foreach_with_internals != NULL)
iface->foreach_with_internals (container, callback, user_data);
else
iface->foreach (container, callback, user_data);
}
/**
* clutter_container_raise_child: (virtual raise)
* @container: a #ClutterContainer
* @actor: the actor to raise
* @sibling: (allow-none): the sibling to raise to, or %NULL to raise
* to the top
*
* Raises @actor to @sibling level, in the depth ordering.
*
* This function calls the #ClutterContainerIface.raise() virtual function,
* which has been deprecated. The default implementation will call
* clutter_actor_set_child_above_sibling().
*
* Since: 0.6
*
* Deprecated: 1.10: Use clutter_actor_set_child_above_sibling() instead.
*/
void
clutter_container_raise_child (ClutterContainer *container,
ClutterActor *actor,
ClutterActor *sibling)
{
ClutterContainerIface *iface;
ClutterActor *self;
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling));
if (actor == sibling)
return;
self = CLUTTER_ACTOR (container);
if (clutter_actor_get_parent (actor) != self)
{
g_warning ("Actor of type '%s' is not a child of the container "
"of type '%s'",
g_type_name (G_OBJECT_TYPE (actor)),
g_type_name (G_OBJECT_TYPE (container)));
return;
}
if (sibling != NULL &&
clutter_actor_get_parent (sibling) != self)
{
g_warning ("Actor of type '%s' is not a child of the container "
"of type '%s'",
g_type_name (G_OBJECT_TYPE (sibling)),
g_type_name (G_OBJECT_TYPE (container)));
return;
}
iface = CLUTTER_CONTAINER_GET_IFACE (container);
#ifdef CLUTTER_ENABLE_DEBUG
if (G_UNLIKELY (_clutter_diagnostic_enabled ()))
{
if (iface->raise != container_real_raise)
_clutter_diagnostic_message ("The ClutterContainer::raise() "
"virtual function has been deprecated "
"and it should not be overridden by "
"newly written code");
}
#endif /* CLUTTER_ENABLE_DEBUG */
iface->raise (container, actor, sibling);
}
/**
* clutter_container_lower_child: (virtual lower)
* @container: a #ClutterContainer
* @actor: the actor to raise
* @sibling: (allow-none): the sibling to lower to, or %NULL to lower
* to the bottom
*
* Lowers @actor to @sibling level, in the depth ordering.
*
* This function calls the #ClutterContainerIface.lower() virtual function,
* which has been deprecated. The default implementation will call
* clutter_actor_set_child_below_sibling().
*
* Since: 0.6
*
* Deprecated: 1.10: Use clutter_actor_set_child_below_sibling() instead.
*/
void
clutter_container_lower_child (ClutterContainer *container,
ClutterActor *actor,
ClutterActor *sibling)
{
ClutterContainerIface *iface;
ClutterActor *self;
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling));
if (actor == sibling)
return;
self = CLUTTER_ACTOR (container);
if (clutter_actor_get_parent (actor) != self)
{
g_warning ("Actor of type '%s' is not a child of the container "
"of type '%s'",
g_type_name (G_OBJECT_TYPE (actor)),
g_type_name (G_OBJECT_TYPE (container)));
return;
}
if (sibling != NULL&&
clutter_actor_get_parent (sibling) != self)
{
g_warning ("Actor of type '%s' is not a child of the container "
"of type '%s'",
g_type_name (G_OBJECT_TYPE (sibling)),
g_type_name (G_OBJECT_TYPE (container)));
return;
}
iface = CLUTTER_CONTAINER_GET_IFACE (container);
#ifdef CLUTTER_ENABLE_DEBUG
if (G_UNLIKELY (_clutter_diagnostic_enabled ()))
{
if (iface->lower != container_real_lower)
_clutter_diagnostic_message ("The ClutterContainer::lower() "
"virtual function has been deprecated "
"and it should not be overridden by "
"newly written code");
}
#endif /* CLUTTER_ENABLE_DEBUG */
iface->lower (container, actor, sibling);
}
/**
* clutter_container_sort_depth_order:
* @container: a #ClutterContainer
*
* Sorts a container's children using their depth. This function should not
* be normally used by applications.
*
* Since: 0.6
*
* Deprecated: 1.10: The #ClutterContainerIface.sort_depth_order() virtual
* function should not be used any more; the default implementation in
* #ClutterContainer does not do anything.
*/
void
clutter_container_sort_depth_order (ClutterContainer *container)
{
ClutterContainerIface *iface;
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
iface = CLUTTER_CONTAINER_GET_IFACE (container);
#ifdef CLUTTER_ENABLE_DEBUG
if (G_UNLIKELY (_clutter_diagnostic_enabled ()))
{
if (iface->sort_depth_order != container_real_sort_depth_order)
_clutter_diagnostic_message ("The ClutterContainer::sort_depth_order() "
"virtual function has been deprecated "
"and it should not be overridden by "
"newly written code");
}
#endif /* CLUTTER_ENABLE_DEBUG */
iface->sort_depth_order (container);
}
/** /**
* clutter_container_find_child_by_name: * clutter_container_find_child_by_name:
* @container: a #ClutterContainer * @container: a #ClutterContainer
@@ -410,6 +847,8 @@ clutter_container_remove_actor (ClutterContainer *container,
* *
* Return value: (transfer none): The child actor with the requested name, * Return value: (transfer none): The child actor with the requested name,
* or %NULL if no actor with that name was found. * or %NULL if no actor with that name was found.
*
* Since: 0.6
*/ */
ClutterActor * ClutterActor *
clutter_container_find_child_by_name (ClutterContainer *container, clutter_container_find_child_by_name (ClutterContainer *container,
@@ -422,7 +861,7 @@ clutter_container_find_child_by_name (ClutterContainer *container,
g_return_val_if_fail (CLUTTER_IS_CONTAINER (container), NULL); g_return_val_if_fail (CLUTTER_IS_CONTAINER (container), NULL);
g_return_val_if_fail (child_name != NULL, NULL); g_return_val_if_fail (child_name != NULL, NULL);
children = clutter_actor_get_children (CLUTTER_ACTOR (container)); children = clutter_container_get_children (container);
for (iter = children; iter; iter = g_list_next (iter)) for (iter = children; iter; iter = g_list_next (iter))
{ {
@@ -519,7 +958,9 @@ destroy_child_meta (ClutterContainer *container,
* *
* Return value: (transfer none): the #ClutterChildMeta for the @actor child * Return value: (transfer none): the #ClutterChildMeta for the @actor child
* of @container or %NULL if the specifiec actor does not exist or the * of @container or %NULL if the specifiec actor does not exist or the
* container is not configured to provide `ClutterChildMeta`s * container is not configured to provide #ClutterChildMeta<!-- -->s
*
* Since: 0.8
*/ */
ClutterChildMeta * ClutterChildMeta *
clutter_container_get_child_meta (ClutterContainer *container, clutter_container_get_child_meta (ClutterContainer *container,
@@ -550,6 +991,8 @@ clutter_container_get_child_meta (ClutterContainer *container,
* #ClutterContainer::add() virtual function implementation. * #ClutterContainer::add() virtual function implementation.
* *
* Applications should not call this function. * Applications should not call this function.
*
* Since: 1.2
*/ */
void void
clutter_container_create_child_meta (ClutterContainer *container, clutter_container_create_child_meta (ClutterContainer *container,
@@ -584,6 +1027,8 @@ clutter_container_create_child_meta (ClutterContainer *container,
* #ClutterContainer::add() virtual function implementation. * #ClutterContainer::add() virtual function implementation.
* *
* Applications should not call this function. * Applications should not call this function.
*
* Since: 1.2
*/ */
void void
clutter_container_destroy_child_meta (ClutterContainer *container, clutter_container_destroy_child_meta (ClutterContainer *container,
@@ -612,6 +1057,8 @@ clutter_container_destroy_child_meta (ClutterContainer *container,
* *
* Return value: (transfer none): The #GParamSpec for the property or %NULL * Return value: (transfer none): The #GParamSpec for the property or %NULL
* if no such property exist. * if no such property exist.
*
* Since: 0.8
*/ */
GParamSpec * GParamSpec *
clutter_container_class_find_child_property (GObjectClass *klass, clutter_container_class_find_child_property (GObjectClass *klass,
@@ -648,7 +1095,9 @@ clutter_container_class_find_child_property (GObjectClass *klass,
* Returns an array of #GParamSpec for all child properties. * Returns an array of #GParamSpec for all child properties.
* *
* Return value: (array length=n_properties) (transfer full): an array * Return value: (array length=n_properties) (transfer full): an array
* of `GParamSpec`s which should be freed after use. * of #GParamSpec<!-- -->s which should be freed after use.
*
* Since: 0.8
*/ */
GParamSpec ** GParamSpec **
clutter_container_class_list_child_properties (GObjectClass *klass, clutter_container_class_list_child_properties (GObjectClass *klass,
@@ -709,6 +1158,8 @@ container_set_child_property (ClutterContainer *container,
* @value: the value. * @value: the value.
* *
* Sets a container-specific property on a child of @container. * Sets a container-specific property on a child of @container.
*
* Since: 0.8
*/ */
void void
clutter_container_child_set_property (ClutterContainer *container, clutter_container_child_set_property (ClutterContainer *container,
@@ -755,6 +1206,8 @@ clutter_container_child_set_property (ClutterContainer *container,
* pairs terminated with NULL. * pairs terminated with NULL.
* *
* Sets container specific properties on the child of a container. * Sets container specific properties on the child of a container.
*
* Since: 0.8
*/ */
void void
clutter_container_child_set (ClutterContainer *container, clutter_container_child_set (ClutterContainer *container,
@@ -848,6 +1301,8 @@ container_get_child_property (ClutterContainer *container,
* Note that clutter_container_child_set_property() is really intended for * Note that clutter_container_child_set_property() is really intended for
* language bindings, clutter_container_child_set() is much more convenient * language bindings, clutter_container_child_set() is much more convenient
* for C programming. * for C programming.
*
* Since: 0.8
*/ */
void void
clutter_container_child_get_property (ClutterContainer *container, clutter_container_child_get_property (ClutterContainer *container,
@@ -899,6 +1354,8 @@ clutter_container_child_get_property (ClutterContainer *container,
* In general, a copy is made of the property contents and the caller is * In general, a copy is made of the property contents and the caller is
* responsible for freeing the memory in the appropriate manner for the type, for * responsible for freeing the memory in the appropriate manner for the type, for
* instance by calling g_free() or g_object_unref(). * instance by calling g_free() or g_object_unref().
*
* Since: 0.8
*/ */
void void
clutter_container_child_get (ClutterContainer *container, clutter_container_child_get (ClutterContainer *container,
@@ -969,6 +1426,8 @@ clutter_container_child_get (ClutterContainer *container,
* Calls the #ClutterContainerIface.child_notify() virtual function * Calls the #ClutterContainerIface.child_notify() virtual function
* of #ClutterContainer. The default implementation will emit the * of #ClutterContainer. The default implementation will emit the
* #ClutterContainer::child-notify signal. * #ClutterContainer::child-notify signal.
*
* Since: 1.6
*/ */
void void
clutter_container_child_notify (ClutterContainer *container, clutter_container_child_notify (ClutterContainer *container,
@@ -985,23 +1444,3 @@ clutter_container_child_notify (ClutterContainer *container,
child, child,
pspec); pspec);
} }
void
_clutter_container_emit_actor_added (ClutterContainer *container,
ClutterActor *actor)
{
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
g_signal_emit (container, container_signals[ACTOR_ADDED], 0, actor);
}
void
_clutter_container_emit_actor_removed (ClutterContainer *container,
ClutterActor *actor)
{
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
g_signal_emit (container, container_signals[ACTOR_REMOVED], 0, actor);
}

View File

@@ -44,12 +44,36 @@ G_BEGIN_DECLS
typedef struct _ClutterContainerIface ClutterContainerIface; typedef struct _ClutterContainerIface ClutterContainerIface;
/**
* ClutterContainer:
*
* #ClutterContainer is an opaque structure whose members cannot be directly
* accessed
*
* Since: 0.4
*/
/** /**
* ClutterContainerIface: * ClutterContainerIface:
* @add: virtual function for adding an actor to the container. This virtual * @add: virtual function for adding an actor to the container. This virtual
* function is deprecated, and it should not be overridden. * function is deprecated, and it should not be overridden.
* @remove: virtual function for removing an actor from the container. This * @remove: virtual function for removing an actor from the container. This
* virtual function is deprecated, and it should not be overridden. * virtual function is deprecated, and it should not be overridden.
* @foreach: virtual function for iterating over the container's children.
* This virtual function is deprecated, and it should not be overridden.
* @foreach_with_internals: virtual functions for iterating over the
* container's children, both added using the #ClutterContainer API
* and internal children. The implementation of this virtual function
* is required only if the #ClutterContainer implementation has
* internal children. This virtual function is deprecated, and it should
* not be overridden.
* @raise: virtual function for raising a child. This virtual function is
* deprecated and it should not be overridden.
* @lower: virtual function for lowering a child. This virtual function is
* deprecated and it should not be overridden.
* @sort_depth_order: virtual function for sorting the children of a
* container depending on their depth. This virtual function is deprecated
* and it should not be overridden.
* @child_meta_type: The GType used for storing auxiliary information about * @child_meta_type: The GType used for storing auxiliary information about
* each of the containers children. * each of the containers children.
* @create_child_meta: virtual function that gets called for each added * @create_child_meta: virtual function that gets called for each added
@@ -58,15 +82,17 @@ typedef struct _ClutterContainerIface ClutterContainerIface;
* fields in the instance and add the record to a data structure for * fields in the instance and add the record to a data structure for
* subsequent access for #ClutterContainerIface::get_child_meta * subsequent access for #ClutterContainerIface::get_child_meta
* @destroy_child_meta: virtual function that gets called when a child is * @destroy_child_meta: virtual function that gets called when a child is
* removed; it should release all resources held by the record * removed; it shuld release all resources held by the record
* @get_child_meta: return the record for a container child * @get_child_meta: return the record for a container child
* @actor_added: class handler for #ClutterContainer::actor-added * @actor_added: class handler for #ClutterContainer::actor-added
* @actor_removed: class handler for #ClutterContainer::actor-removed * @actor_removed: class handler for #ClutterContainer::actor-removed
* @child_notify: class handler for #ClutterContainer::child-notify * @child_notify: class handler for #ClutterContainer::child-notify
* *
* Base interface for container actors. The @add and @remove * Base interface for container actors. The @add, @remove and @foreach
* virtual functions must be provided by any implementation; the other * virtual functions must be provided by any implementation; the other
* virtual functions are optional. * virtual functions are optional.
*
* Since: 0.4
*/ */
struct _ClutterContainerIface struct _ClutterContainerIface
{ {
@@ -78,6 +104,22 @@ struct _ClutterContainerIface
ClutterActor *actor); ClutterActor *actor);
void (* remove) (ClutterContainer *container, void (* remove) (ClutterContainer *container,
ClutterActor *actor); ClutterActor *actor);
void (* foreach) (ClutterContainer *container,
ClutterCallback callback,
gpointer user_data);
void (* foreach_with_internals) (ClutterContainer *container,
ClutterCallback callback,
gpointer user_data);
/* child stacking */
void (* raise) (ClutterContainer *container,
ClutterActor *actor,
ClutterActor *sibling);
void (* lower) (ClutterContainer *container,
ClutterActor *actor,
ClutterActor *sibling);
void (* sort_depth_order) (ClutterContainer *container);
/* ClutterChildMeta management */ /* ClutterChildMeta management */
GType child_meta_type; GType child_meta_type;

View File

@@ -36,8 +36,7 @@ void _clutter_content_detached (ClutterContent *conte
void _clutter_content_paint_content (ClutterContent *content, void _clutter_content_paint_content (ClutterContent *content,
ClutterActor *actor, ClutterActor *actor,
ClutterPaintNode *node, ClutterPaintNode *node);
ClutterPaintContext *paint_context);
G_END_DECLS G_END_DECLS

View File

@@ -23,15 +23,17 @@
*/ */
/** /**
* ClutterContent: * SECTION:clutter-content
* * @Title: ClutterContent
* Delegate for painting the content of an actor * @Short_Description: Delegate for painting the content of an actor
* *
* #ClutterContent is an interface to implement types responsible for * #ClutterContent is an interface to implement types responsible for
* painting the content of a [class@Actor]. * painting the content of a #ClutterActor.
* *
* Multiple actors can use the same #ClutterContent instance, in order * Multiple actors can use the same #ClutterContent instance, in order
* to share the resources associated with painting the same content.. * to share the resources associated with painting the same content.
*
* #ClutterContent is available since Clutter 1.10.
*/ */
#include "clutter-build-config.h" #include "clutter-build-config.h"
@@ -96,8 +98,7 @@ clutter_content_real_invalidate_size (ClutterContent *content)
static void static void
clutter_content_real_paint_content (ClutterContent *content, clutter_content_real_paint_content (ClutterContent *content,
ClutterActor *actor, ClutterActor *actor,
ClutterPaintNode *context, ClutterPaintNode *context)
ClutterPaintContext *paint_context)
{ {
} }
@@ -120,6 +121,8 @@ clutter_content_default_init (ClutterContentInterface *iface)
* *
* This signal is emitted each time a #ClutterContent implementation is * This signal is emitted each time a #ClutterContent implementation is
* assigned to a #ClutterActor. * assigned to a #ClutterActor.
*
* Since: 1.10
*/ */
content_signals[ATTACHED] = content_signals[ATTACHED] =
g_signal_new (I_("attached"), g_signal_new (I_("attached"),
@@ -137,6 +140,8 @@ clutter_content_default_init (ClutterContentInterface *iface)
* *
* This signal is emitted each time a #ClutterContent implementation is * This signal is emitted each time a #ClutterContent implementation is
* removed from a #ClutterActor. * removed from a #ClutterActor.
*
* Since: 1.10
*/ */
content_signals[DETACHED] = content_signals[DETACHED] =
g_signal_new (I_("detached"), g_signal_new (I_("detached"),
@@ -157,6 +162,8 @@ clutter_content_default_init (ClutterContentInterface *iface)
* This function should be called by #ClutterContent implementations when * This function should be called by #ClutterContent implementations when
* they change the way a the content should be painted regardless of the * they change the way a the content should be painted regardless of the
* actor state. * actor state.
*
* Since: 1.10
*/ */
void void
clutter_content_invalidate (ClutterContent *content) clutter_content_invalidate (ClutterContent *content)
@@ -293,8 +300,7 @@ _clutter_content_detached (ClutterContent *content,
* _clutter_content_paint_content: * _clutter_content_paint_content:
* @content: a #ClutterContent * @content: a #ClutterContent
* @actor: a #ClutterActor * @actor: a #ClutterActor
* @node: a #ClutterPaintNode * @context: a #ClutterPaintNode
* @paint_context: a #ClutterPaintContext
* *
* Creates the render tree for the @content and @actor. * Creates the render tree for the @content and @actor.
* *
@@ -304,18 +310,16 @@ _clutter_content_detached (ClutterContent *content,
void void
_clutter_content_paint_content (ClutterContent *content, _clutter_content_paint_content (ClutterContent *content,
ClutterActor *actor, ClutterActor *actor,
ClutterPaintNode *node, ClutterPaintNode *node)
ClutterPaintContext *paint_context)
{ {
CLUTTER_CONTENT_GET_IFACE (content)->paint_content (content, actor, node, CLUTTER_CONTENT_GET_IFACE (content)->paint_content (content, actor, node);
paint_context);
} }
/** /**
* clutter_content_get_preferred_size: * clutter_content_get_preferred_size:
* @content: a #ClutterContent * @content: a #ClutterContent
* @width: (out) (optional): return location for the natural width of the content * @width: (out): return location for the natural width of the content
* @height: (out) (optional): return location for the natural height of the content * @height: (out): return location for the natural height of the content
* *
* Retrieves the natural size of the @content, if any. * Retrieves the natural size of the @content, if any.
* *
@@ -325,6 +329,8 @@ _clutter_content_paint_content (ClutterContent *content,
* *
* Return value: %TRUE if the content has a preferred size, and %FALSE * Return value: %TRUE if the content has a preferred size, and %FALSE
* otherwise * otherwise
*
* Since: 1.10
*/ */
gboolean gboolean
clutter_content_get_preferred_size (ClutterContent *content, clutter_content_get_preferred_size (ClutterContent *content,

View File

@@ -53,6 +53,8 @@ G_DECLARE_INTERFACE (ClutterContent, clutter_content, CLUTTER, CONTENT, GObject)
* *
* The #ClutterContentInterface structure contains only * The #ClutterContentInterface structure contains only
* private data. * private data.
*
* Since: 1.10
*/ */
struct _ClutterContentInterface struct _ClutterContentInterface
{ {
@@ -65,8 +67,7 @@ struct _ClutterContentInterface
gfloat *height); gfloat *height);
void (* paint_content) (ClutterContent *content, void (* paint_content) (ClutterContent *content,
ClutterActor *actor, ClutterActor *actor,
ClutterPaintNode *node, ClutterPaintNode *node);
ClutterPaintContext *paint_context);
void (* attached) (ClutterContent *content, void (* attached) (ClutterContent *content,
ClutterActor *actor); ClutterActor *actor);

View File

@@ -1,92 +0,0 @@
/*
* Copyright (C) 2007,2008,2009,2010,2011 Intel Corporation.
* Copyright (C) 2020 Red Hat Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "clutter-build-config.h"
#include "clutter-damage-history.h"
#define DAMAGE_HISTORY_LENGTH 0x10
struct _ClutterDamageHistory
{
cairo_region_t *damages[DAMAGE_HISTORY_LENGTH];
int index;
};
ClutterDamageHistory *
clutter_damage_history_new (void)
{
ClutterDamageHistory *history;
history = g_new0 (ClutterDamageHistory, 1);
return history;
}
void
clutter_damage_history_free (ClutterDamageHistory *history)
{
int i;
for (i = 0; i < G_N_ELEMENTS (history->damages); i++)
g_clear_pointer (&history->damages[i], cairo_region_destroy);
g_free (history);
}
gboolean
clutter_damage_history_is_age_valid (ClutterDamageHistory *history,
int age)
{
if (age >= DAMAGE_HISTORY_LENGTH ||
age < 1)
return FALSE;
if (!clutter_damage_history_lookup (history, age))
return FALSE;
return TRUE;
}
void
clutter_damage_history_record (ClutterDamageHistory *history,
const cairo_region_t *damage)
{
g_clear_pointer (&history->damages[history->index], cairo_region_destroy);
history->damages[history->index] = cairo_region_copy (damage);
}
static inline int
step_damage_index (int current,
int diff)
{
return (current + diff) & (DAMAGE_HISTORY_LENGTH - 1);
}
void
clutter_damage_history_step (ClutterDamageHistory *history)
{
history->index = step_damage_index (history->index, 1);
}
const cairo_region_t *
clutter_damage_history_lookup (ClutterDamageHistory *history,
int age)
{
return history->damages[step_damage_index (history->index, -age)];
}

View File

@@ -1,50 +0,0 @@
/*
* Copyright (C) 2007,2008,2009,2010,2011 Intel Corporation.
* Copyright (C) 2020 Red Hat Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CLUTTER_DAMAGE_HISTORY_H
#define CLUTTER_DAMAGE_HISTORY_H
#include <cairo.h>
#include <glib.h>
#include "clutter-macros.h"
typedef struct _ClutterDamageHistory ClutterDamageHistory;
CLUTTER_EXPORT
ClutterDamageHistory * clutter_damage_history_new (void);
CLUTTER_EXPORT
void clutter_damage_history_free (ClutterDamageHistory *history);
CLUTTER_EXPORT
gboolean clutter_damage_history_is_age_valid (ClutterDamageHistory *history,
int age);
CLUTTER_EXPORT
void clutter_damage_history_record (ClutterDamageHistory *history,
const cairo_region_t *damage);
CLUTTER_EXPORT
void clutter_damage_history_step (ClutterDamageHistory *history);
CLUTTER_EXPORT
const cairo_region_t * clutter_damage_history_lookup (ClutterDamageHistory *history,
int age);
#endif /* CLUTTER_DAMAGE_HISTORY_H */

View File

@@ -6,6 +6,45 @@
G_BEGIN_DECLS G_BEGIN_DECLS
typedef enum
{
CLUTTER_DEBUG_MISC = 1 << 0,
CLUTTER_DEBUG_ACTOR = 1 << 1,
CLUTTER_DEBUG_TEXTURE = 1 << 2,
CLUTTER_DEBUG_EVENT = 1 << 3,
CLUTTER_DEBUG_PAINT = 1 << 4,
CLUTTER_DEBUG_PANGO = 1 << 5,
CLUTTER_DEBUG_BACKEND = 1 << 6,
CLUTTER_DEBUG_SCHEDULER = 1 << 7,
CLUTTER_DEBUG_SCRIPT = 1 << 8,
CLUTTER_DEBUG_SHADER = 1 << 9,
CLUTTER_DEBUG_MULTISTAGE = 1 << 10,
CLUTTER_DEBUG_ANIMATION = 1 << 11,
CLUTTER_DEBUG_LAYOUT = 1 << 12,
CLUTTER_DEBUG_PICK = 1 << 13,
CLUTTER_DEBUG_EVENTLOOP = 1 << 14,
CLUTTER_DEBUG_CLIPPING = 1 << 15,
CLUTTER_DEBUG_OOB_TRANSFORMS = 1 << 16
} ClutterDebugFlag;
typedef enum
{
CLUTTER_DEBUG_NOP_PICKING = 1 << 0,
} ClutterPickDebugFlag;
typedef enum
{
CLUTTER_DEBUG_DISABLE_SWAP_EVENTS = 1 << 0,
CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS = 1 << 1,
CLUTTER_DEBUG_REDRAWS = 1 << 2,
CLUTTER_DEBUG_PAINT_VOLUMES = 1 << 3,
CLUTTER_DEBUG_DISABLE_CULLING = 1 << 4,
CLUTTER_DEBUG_DISABLE_OFFSCREEN_REDIRECT = 1 << 5,
CLUTTER_DEBUG_CONTINUOUS_REDRAW = 1 << 6,
CLUTTER_DEBUG_PAINT_DEFORM_TILES = 1 << 7,
CLUTTER_DEBUG_PAINT_DAMAGE_REGION = 1 << 8,
} ClutterDrawDebugFlag;
#ifdef CLUTTER_ENABLE_DEBUG #ifdef CLUTTER_ENABLE_DEBUG
#define CLUTTER_HAS_DEBUG(type) ((clutter_debug_flags & CLUTTER_DEBUG_##type) != FALSE) #define CLUTTER_HAS_DEBUG(type) ((clutter_debug_flags & CLUTTER_DEBUG_##type) != FALSE)
@@ -15,7 +54,7 @@ G_BEGIN_DECLS
/* Try the GCC extension for valists in macros */ /* Try the GCC extension for valists in macros */
#define CLUTTER_NOTE(type,x,a...) G_STMT_START { \ #define CLUTTER_NOTE(type,x,a...) G_STMT_START { \
if (G_UNLIKELY (CLUTTER_HAS_DEBUG (type))) { \ if (G_UNLIKELY (CLUTTER_HAS_DEBUG (type))) { \
_clutter_debug_message ("[" #type "]: " x, ##a); \ _clutter_debug_message ("[" #type "]:" G_STRLOC ": " x, ##a); \
} } G_STMT_END } } G_STMT_END
#else /* !__GNUC__ */ #else /* !__GNUC__ */
@@ -26,7 +65,7 @@ G_BEGIN_DECLS
#define CLUTTER_NOTE(type,...) G_STMT_START { \ #define CLUTTER_NOTE(type,...) G_STMT_START { \
if (G_UNLIKELY (CLUTTER_HAS_DEBUG (type))) { \ if (G_UNLIKELY (CLUTTER_HAS_DEBUG (type))) { \
gchar *_fmt = g_strdup_printf (__VA_ARGS__); \ gchar *_fmt = g_strdup_printf (__VA_ARGS__); \
_clutter_debug_message ("[" #type "]: %s", _fmt); \ _clutter_debug_message ("[" #type "]:" G_STRLOC ": %s", _fmt); \
g_free (_fmt); \ g_free (_fmt); \
} } G_STMT_END } } G_STMT_END
#endif #endif
@@ -41,7 +80,6 @@ G_BEGIN_DECLS
extern guint clutter_debug_flags; extern guint clutter_debug_flags;
extern guint clutter_pick_debug_flags; extern guint clutter_pick_debug_flags;
extern guint clutter_paint_debug_flags; extern guint clutter_paint_debug_flags;
extern int clutter_max_render_time_constant_us;
void _clutter_debug_messagev (const char *format, void _clutter_debug_messagev (const char *format,
va_list var_args) G_GNUC_PRINTF (1, 0); va_list var_args) G_GNUC_PRINTF (1, 0);

View File

@@ -26,9 +26,10 @@
*/ */
/** /**
* ClutterDeformEffect: * SECTION:clutter-deform-effect
* * @Title: ClutterDeformEffect
* A base class for effects deforming the geometry of an actor * @Short_Description: A base class for effects deforming the geometry
* of an actor
* *
* #ClutterDeformEffect is an abstract class providing all the plumbing * #ClutterDeformEffect is an abstract class providing all the plumbing
* for creating effects that result in the deformation of an actor's * for creating effects that result in the deformation of an actor's
@@ -38,6 +39,8 @@
* a #ClutterActor and then the Cogl vertex buffers API to submit the * a #ClutterActor and then the Cogl vertex buffers API to submit the
* geometry to the GPU. * geometry to the GPU.
* *
* #ClutterDeformEffect is available since Clutter 1.4
*
* ## Implementing ClutterDeformEffect * ## Implementing ClutterDeformEffect
* *
* Sub-classes of #ClutterDeformEffect should override the * Sub-classes of #ClutterDeformEffect should override the
@@ -50,16 +53,14 @@
#include "clutter-build-config.h" #include "clutter-build-config.h"
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include "clutter-deform-effect.h" #include "clutter-deform-effect.h"
#include <cogl/cogl.h> #include <cogl/cogl.h>
#include "clutter-color.h"
#include "clutter-debug.h" #include "clutter-debug.h"
#include "clutter-enum-types.h" #include "clutter-enum-types.h"
#include "clutter-offscreen-effect-private.h" #include "clutter-offscreen-effect-private.h"
#include "clutter-paint-node.h"
#include "clutter-paint-nodes.h"
#include "clutter-private.h" #include "clutter-private.h"
#define DEFAULT_N_TILES 32 #define DEFAULT_N_TILES 32
@@ -128,7 +129,8 @@ clutter_deform_effect_deform_vertex (ClutterDeformEffect *effect,
static void static void
vbo_invalidate (ClutterActor *actor, vbo_invalidate (ClutterActor *actor,
GParamSpec *pspec, const ClutterActorBox *allocation,
ClutterAllocationFlags flags,
ClutterDeformEffect *effect) ClutterDeformEffect *effect)
{ {
effect->priv->is_dirty = TRUE; effect->priv->is_dirty = TRUE;
@@ -145,7 +147,7 @@ clutter_deform_effect_set_actor (ClutterActorMeta *meta,
ClutterActor *old_actor = clutter_actor_meta_get_actor (meta); ClutterActor *old_actor = clutter_actor_meta_get_actor (meta);
if (old_actor != NULL) if (old_actor != NULL)
g_clear_signal_handler (&priv->allocation_id, old_actor); g_signal_handler_disconnect (old_actor, priv->allocation_id);
priv->allocation_id = 0; priv->allocation_id = 0;
} }
@@ -154,7 +156,7 @@ clutter_deform_effect_set_actor (ClutterActorMeta *meta,
* changes * changes
*/ */
if (actor != NULL) if (actor != NULL)
priv->allocation_id = g_signal_connect (actor, "notify::allocation", priv->allocation_id = g_signal_connect (actor, "allocation-changed",
G_CALLBACK (vbo_invalidate), G_CALLBACK (vbo_invalidate),
meta); meta);
@@ -164,17 +166,18 @@ clutter_deform_effect_set_actor (ClutterActorMeta *meta,
} }
static void static void
clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect, clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect)
ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{ {
ClutterDeformEffect *self= CLUTTER_DEFORM_EFFECT (effect); ClutterDeformEffect *self= CLUTTER_DEFORM_EFFECT (effect);
ClutterDeformEffectPrivate *priv = self->priv; ClutterDeformEffectPrivate *priv = self->priv;
CoglHandle material;
CoglPipeline *pipeline; CoglPipeline *pipeline;
CoglDepthState depth_state; CoglDepthState depth_state;
CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
if (priv->is_dirty) if (priv->is_dirty)
{ {
ClutterRect rect;
gboolean mapped_buffer; gboolean mapped_buffer;
CoglVertexP3T2C4 *verts; CoglVertexP3T2C4 *verts;
ClutterActor *actor; ClutterActor *actor;
@@ -188,7 +191,12 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect,
/* if we don't have a target size, fall back to the actor's /* if we don't have a target size, fall back to the actor's
* allocation, though wrong it might be * allocation, though wrong it might be
*/ */
if (!clutter_offscreen_effect_get_target_size (effect, &width, &height)) if (clutter_offscreen_effect_get_target_rect (effect, &rect))
{
width = clutter_rect_get_width (&rect);
height = clutter_rect_get_height (&rect);
}
else
clutter_actor_get_size (actor, &width, &height); clutter_actor_get_size (actor, &width, &height);
/* XXX ideally, the sub-classes should tell us what they /* XXX ideally, the sub-classes should tell us what they
@@ -268,7 +276,8 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect,
priv->is_dirty = FALSE; priv->is_dirty = FALSE;
} }
pipeline = clutter_offscreen_effect_get_pipeline (effect); material = clutter_offscreen_effect_get_target (effect);
pipeline = COGL_PIPELINE (material);
/* enable depth testing */ /* enable depth testing */
cogl_depth_state_init (&depth_state); cogl_depth_state_init (&depth_state);
@@ -282,22 +291,12 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect,
COGL_PIPELINE_CULL_FACE_MODE_BACK); COGL_PIPELINE_CULL_FACE_MODE_BACK);
/* draw the front */ /* draw the front */
if (pipeline != NULL) if (material != NULL)
{ cogl_framebuffer_draw_primitive (fb, pipeline, priv->primitive);
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 */ /* draw the back */
if (priv->back_pipeline != NULL) if (priv->back_pipeline != NULL)
{ {
ClutterPaintNode *back_node;
CoglPipeline *back_pipeline; CoglPipeline *back_pipeline;
/* We probably shouldn't be modifying the user's material so /* We probably shouldn't be modifying the user's material so
@@ -307,30 +306,20 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect,
cogl_pipeline_set_cull_face_mode (back_pipeline, cogl_pipeline_set_cull_face_mode (back_pipeline,
COGL_PIPELINE_CULL_FACE_MODE_FRONT); COGL_PIPELINE_CULL_FACE_MODE_FRONT);
cogl_framebuffer_draw_primitive (fb, back_pipeline, priv->primitive);
back_node = clutter_pipeline_node_new (back_pipeline);
clutter_paint_node_set_static_name (back_node,
"ClutterDeformEffect (back)");
clutter_paint_node_add_child (node, back_node);
clutter_paint_node_add_primitive (back_node, priv->primitive);
clutter_paint_node_unref (back_node);
cogl_object_unref (back_pipeline); cogl_object_unref (back_pipeline);
} }
if (G_UNLIKELY (priv->lines_primitive != NULL)) if (G_UNLIKELY (priv->lines_primitive != NULL))
{ {
const ClutterColor *red; CoglContext *ctx =
ClutterPaintNode *lines_node; clutter_backend_get_cogl_context (clutter_get_default_backend ());
CoglPipeline *lines_pipeline = cogl_pipeline_new (ctx);
red = clutter_color_get_static (CLUTTER_COLOR_RED); cogl_pipeline_set_color4f (lines_pipeline, 1.0, 0, 0, 1.0);
cogl_framebuffer_draw_primitive (fb, lines_pipeline,
lines_node = clutter_color_node_new (red); priv->lines_primitive);
clutter_paint_node_set_static_name (lines_node, cogl_object_unref (lines_pipeline);
"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);
} }
} }
@@ -593,6 +582,8 @@ clutter_deform_effect_class_init (ClutterDeformEffectClass *klass)
* *
* The number of horizontal tiles. The bigger the number, the * The number of horizontal tiles. The bigger the number, the
* smaller the tiles * smaller the tiles
*
* Since: 1.4
*/ */
obj_props[PROP_X_TILES] = obj_props[PROP_X_TILES] =
g_param_spec_uint ("x-tiles", g_param_spec_uint ("x-tiles",
@@ -607,6 +598,8 @@ clutter_deform_effect_class_init (ClutterDeformEffectClass *klass)
* *
* The number of vertical tiles. The bigger the number, the * The number of vertical tiles. The bigger the number, the
* smaller the tiles * smaller the tiles
*
* Since: 1.4
*/ */
obj_props[PROP_Y_TILES] = obj_props[PROP_Y_TILES] =
g_param_spec_uint ("y-tiles", g_param_spec_uint ("y-tiles",
@@ -623,6 +616,8 @@ clutter_deform_effect_class_init (ClutterDeformEffectClass *klass)
* to which this effect has been applied * to which this effect has been applied
* *
* By default, no material will be used * By default, no material will be used
*
* Since: 1.4
*/ */
obj_props[PROP_BACK_MATERIAL] = obj_props[PROP_BACK_MATERIAL] =
g_param_spec_boxed ("back-material", g_param_spec_boxed ("back-material",
@@ -663,6 +658,8 @@ clutter_deform_effect_init (ClutterDeformEffect *self)
* *
* The #ClutterDeformEffect will take a reference on the material's * The #ClutterDeformEffect will take a reference on the material's
* handle * handle
*
* Since: 1.4
*/ */
void void
clutter_deform_effect_set_back_material (ClutterDeformEffect *effect, clutter_deform_effect_set_back_material (ClutterDeformEffect *effect,
@@ -694,6 +691,8 @@ clutter_deform_effect_set_back_material (ClutterDeformEffect *effect,
* Return value: (transfer none): a handle for the material, or %NULL. * Return value: (transfer none): a handle for the material, or %NULL.
* The returned material is owned by the #ClutterDeformEffect and it * The returned material is owned by the #ClutterDeformEffect and it
* should not be freed directly * should not be freed directly
*
* Since: 1.4
*/ */
CoglHandle CoglHandle
clutter_deform_effect_get_back_material (ClutterDeformEffect *effect) clutter_deform_effect_get_back_material (ClutterDeformEffect *effect)
@@ -714,6 +713,8 @@ clutter_deform_effect_get_back_material (ClutterDeformEffect *effect)
* *
* More tiles allow a finer grained deformation at the expenses * More tiles allow a finer grained deformation at the expenses
* of computation * of computation
*
* Since: 1.4
*/ */
void void
clutter_deform_effect_set_n_tiles (ClutterDeformEffect *effect, clutter_deform_effect_set_n_tiles (ClutterDeformEffect *effect,
@@ -767,6 +768,8 @@ clutter_deform_effect_set_n_tiles (ClutterDeformEffect *effect,
* *
* Retrieves the number of horizontal and vertical tiles used to sub-divide * Retrieves the number of horizontal and vertical tiles used to sub-divide
* the actor's geometry during the effect * the actor's geometry during the effect
*
* Since: 1.4
*/ */
void void
clutter_deform_effect_get_n_tiles (ClutterDeformEffect *effect, clutter_deform_effect_get_n_tiles (ClutterDeformEffect *effect,
@@ -786,8 +789,10 @@ clutter_deform_effect_get_n_tiles (ClutterDeformEffect *effect,
* clutter_deform_effect_invalidate: * clutter_deform_effect_invalidate:
* @effect: a #ClutterDeformEffect * @effect: a #ClutterDeformEffect
* *
* Invalidates the `effect`'s vertices and, if it is associated * Invalidates the @effect<!-- -->'s vertices and, if it is associated
* to an actor, it will queue a redraw * to an actor, it will queue a redraw
*
* Since: 1.4
*/ */
void void
clutter_deform_effect_invalidate (ClutterDeformEffect *effect) clutter_deform_effect_invalidate (ClutterDeformEffect *effect)

View File

@@ -45,6 +45,14 @@ typedef struct _ClutterDeformEffect ClutterDeformEffect;
typedef struct _ClutterDeformEffectPrivate ClutterDeformEffectPrivate; typedef struct _ClutterDeformEffectPrivate ClutterDeformEffectPrivate;
typedef struct _ClutterDeformEffectClass ClutterDeformEffectClass; typedef struct _ClutterDeformEffectClass ClutterDeformEffectClass;
/**
* ClutterDeformEffect:
*
* The #ClutterDeformEffect structure contains
* only private data and should be accessed using the provided API
*
* Since: 1.4
*/
struct _ClutterDeformEffect struct _ClutterDeformEffect
{ {
/*< private >*/ /*< private >*/
@@ -60,6 +68,8 @@ struct _ClutterDeformEffect
* *
* The #ClutterDeformEffectClass structure contains * The #ClutterDeformEffectClass structure contains
* only private data * only private data
*
* Since: 1.4
*/ */
struct _ClutterDeformEffectClass struct _ClutterDeformEffectClass
{ {

View File

@@ -3,8 +3,27 @@
#define __CLUTTER_DEPRECATED_H_INSIDE__ #define __CLUTTER_DEPRECATED_H_INSIDE__
#include "deprecated/clutter-box-layout.h" #include "deprecated/clutter-actor.h"
#include "deprecated/clutter-alpha.h"
#include "deprecated/clutter-animatable.h"
#include "deprecated/clutter-animation.h"
#include "deprecated/clutter-behaviour.h"
#include "deprecated/clutter-behaviour-depth.h"
#include "deprecated/clutter-behaviour-opacity.h"
#include "deprecated/clutter-behaviour-scale.h"
#include "deprecated/clutter-bin-layout.h"
#include "deprecated/clutter-box.h"
#include "deprecated/clutter-cairo-texture.h"
#include "deprecated/clutter-container.h" #include "deprecated/clutter-container.h"
#include "deprecated/clutter-group.h"
#include "deprecated/clutter-keysyms.h"
#include "deprecated/clutter-rectangle.h"
#include "deprecated/clutter-stage-manager.h"
#include "deprecated/clutter-stage.h"
#include "deprecated/clutter-state.h"
#include "deprecated/clutter-table-layout.h"
#include "deprecated/clutter-texture.h"
#include "deprecated/clutter-timeline.h"
#undef __CLUTTER_DEPRECATED_H_INSIDE__ #undef __CLUTTER_DEPRECATED_H_INSIDE__

Some files were not shown because too many files have changed in this diff Show More