Compare commits
1 Commits
citadel-48
...
dcvviewer
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1484fa6c2 |
@@ -1,27 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2021 The GTK Authors
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.[ch]]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
# For the legacy tabs which still exist in the code:
|
||||
tab_width = 8
|
||||
|
||||
[*.xml]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
[meson.build]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
[*.md]
|
||||
max_line_length = 80
|
||||
111
.gitignore
vendored
111
.gitignore
vendored
@@ -1,12 +1,105 @@
|
||||
build-aux
|
||||
compile
|
||||
config.h
|
||||
config.h.in
|
||||
ltmain.sh
|
||||
missing
|
||||
50-mutter-navigation.xml
|
||||
50-mutter-system.xml
|
||||
50-mutter-windows.xml
|
||||
mutter.desktop
|
||||
mutter-wayland.desktop
|
||||
*.o
|
||||
*.a
|
||||
*.lo
|
||||
*.la
|
||||
.libs
|
||||
*.swp
|
||||
*.gir
|
||||
*.typelib
|
||||
*.gmo
|
||||
*.make
|
||||
*.log
|
||||
*.trs
|
||||
*~
|
||||
POTFILES
|
||||
Makevars.template
|
||||
po/*.header
|
||||
po/*.pot
|
||||
po/*.sed
|
||||
po/*.sin
|
||||
Rules-quot
|
||||
libmutter.pc
|
||||
mutter
|
||||
mutter-restart-helper
|
||||
mutter-test-client
|
||||
mutter-test-runner
|
||||
mutter-test-unit-tests
|
||||
mutter-test-headless-start-test
|
||||
mutter-all.test
|
||||
org.gnome.mutter.gschema.valid
|
||||
org.gnome.mutter.gschema.xml
|
||||
org.gnome.mutter.wayland.gschema.valid
|
||||
org.gnome.mutter.wayland.gschema.xml
|
||||
testasyncgetprop
|
||||
testboxes
|
||||
testgradient
|
||||
INSTALL
|
||||
meta-enum-types.[ch]
|
||||
src/stamp-meta-enum-types.h
|
||||
src/meta-dbus-display-config.[ch]
|
||||
src/meta-dbus-idle-monitor.[ch]
|
||||
src/meta-dbus-login1.[ch]
|
||||
src/meta-dbus-remote-desktop.[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-server-protocol.h
|
||||
src/xdg-shell-unstable-v*-protocol.c
|
||||
src/xdg-shell-unstable-v*-server-protocol.h
|
||||
src/pointer-gestures-unstable-v*-protocol.c
|
||||
src/pointer-gestures-unstable-v*-server-protocol.h
|
||||
src/relative-pointer-unstable-v*-protocol.c
|
||||
src/relative-pointer-unstable-v*-server-protocol.h
|
||||
src/pointer-constraints-unstable-v*-protocol.c
|
||||
src/pointer-constraints-unstable-v*-server-protocol.h
|
||||
src/xdg-foreign-unstable-v*-protocol.c
|
||||
src/xdg-foreign-unstable-v*-server-protocol.h
|
||||
src/xdg-output-unstable-v1-protocol.c
|
||||
src/xdg-output-unstable-v1-server-protocol.h
|
||||
src/xwayland-keyboard-grab-unstable-v1-protocol.c
|
||||
src/xwayland-keyboard-grab-unstable-v1-server-protocol.h
|
||||
src/tablet-unstable-v*-protocol.c
|
||||
src/tablet-unstable-v*-server-protocol.h
|
||||
src/text-input-unstable-v*-protocol.c
|
||||
src/text-input-unstable-v*-server-protocol.h
|
||||
src/keyboard-shortcuts-inhibit-unstable-v*-protocol.c
|
||||
src/keyboard-shortcuts-inhibit-unstable-v*-server-protocol.h
|
||||
src/linux-dmabuf-unstable-v*-protocol.c
|
||||
src/linux-dmabuf-unstable-v*-server-protocol.h
|
||||
src/xdg-shell-protocol.c
|
||||
src/xdg-shell-server-protocol.h
|
||||
src/wayland-eglstream-controller-server-protocol.h
|
||||
src/meta/meta-version.h
|
||||
src/libmutter-*.pc
|
||||
doc/reference/*.args
|
||||
doc/reference/*.bak
|
||||
doc/reference/*.hierarchy
|
||||
doc/reference/*.interfaces
|
||||
doc/reference/*.prerequisites
|
||||
doc/reference/*.signals
|
||||
doc/reference/*.stamp
|
||||
doc/reference/html/
|
||||
doc/reference/xml/
|
||||
doc/reference/meta-decl-list.txt
|
||||
doc/reference/meta-decl.txt
|
||||
doc/reference/meta-overrides.txt
|
||||
doc/reference/meta-undeclared.txt
|
||||
doc/reference/meta-undocumented.txt
|
||||
doc/reference/meta-unused.txt
|
||||
doc/reference/meta-docs.sgml
|
||||
doc/reference/meta.types
|
||||
.dirstamp
|
||||
**/tags.*
|
||||
subprojects/gvdb/
|
||||
subprojects/sysprof/
|
||||
__pycache__/
|
||||
.buildconfig
|
||||
.vscode
|
||||
runtime-dir
|
||||
build
|
||||
_build
|
||||
builddir
|
||||
build/
|
||||
|
||||
838
.gitlab-ci.yml
838
.gitlab-ci.yml
@@ -1,835 +1,63 @@
|
||||
include:
|
||||
- remote: 'https://gitlab.gnome.org/Infrastructure/freedesktop-ci-templates/-/raw/145b1bc7ef1702d2bd71584010d7113c6786a506/templates/fedora.yml'
|
||||
- remote: 'https://gitlab.gnome.org/Infrastructure/freedesktop-ci-templates/-/raw/34f4ade99434043f88e164933f570301fd18b125/templates/ci-fairy.yml'
|
||||
- component: gitlab.gnome.org/GNOME/citemplates/release-service@master
|
||||
inputs:
|
||||
job-stage: deploy
|
||||
dist-job-name: "dist-mutter-tarball"
|
||||
tarball-artifact-path: $TARBALL_ARTIFACT_PATH
|
||||
- component: gitlab.gnome.org/GNOME/citemplates/gnomeos-build-sysext@1.0.0-alpha.1
|
||||
inputs:
|
||||
meson-options:
|
||||
-Dxwayland_initfd=enabled
|
||||
-Dprofiler=true
|
||||
-Dbash_completion=false
|
||||
|
||||
build-sysext:
|
||||
before_script:
|
||||
- .gitlab-ci/install-gnomeos-sysext-dependencies.sh $CI_PROJECT_DIR/extension
|
||||
# x86_64_v2 runners hang on pulling the docker image. This should be removed
|
||||
# when the runners are all updated.
|
||||
# https://gitlab.gnome.org/Infrastructure/Infrastructure/-/issues/1665
|
||||
tags:
|
||||
- x86_64_v3
|
||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v2
|
||||
|
||||
stages:
|
||||
- review
|
||||
- prepare
|
||||
- code-review
|
||||
- build
|
||||
- test
|
||||
- analyze
|
||||
- docs
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
FDO_UPSTREAM_REPO: GNOME/mutter
|
||||
TARBALL_ARTIFACT_PATH: build/meson-dist/$CI_PROJECT_NAME-$CI_COMMIT_TAG.tar.xz
|
||||
|
||||
.skip-git-clone:
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
|
||||
.mutter.git-clone:
|
||||
extends:
|
||||
- .skip-git-clone
|
||||
variables:
|
||||
MUTTER_CLONE_PATH: $CI_BUILDS_DIR/$CI_PROJECT_PATH
|
||||
MUTTER_CLONE_DEPTH: 1
|
||||
before_script: |
|
||||
if [ -n "$MUTTER_CLONE_PATH" ]; then
|
||||
set -x
|
||||
uri="$CI_REPOSITORY_URL"
|
||||
if [ -n "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" ]; then
|
||||
uri="$CI_MERGE_REQUEST_SOURCE_PROJECT_URL.git"
|
||||
branch="$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"
|
||||
elif [ -n "$CI_COMMIT_TAG" ]; then
|
||||
branch="$CI_COMMIT_TAG"
|
||||
elif [ -n "$CI_COMMIT_BRANCH" ]; then
|
||||
branch="$CI_COMMIT_BRANCH"
|
||||
else
|
||||
branch="$CI_DEFAULT_BRANCH"
|
||||
fi
|
||||
if [ ! -d "$MUTTER_CLONE_PATH" ] || [ -z "$(ls -A "$MUTTER_CLONE_PATH")" ]; then
|
||||
git clone --depth $MUTTER_CLONE_DEPTH "$uri" "$MUTTER_CLONE_PATH" -b "$branch"
|
||||
elif [ ! -d "$MUTTER_CLONE_PATH/.git" ]; then
|
||||
git clone --bare --depth $MUTTER_CLONE_DEPTH "$uri" "$MUTTER_CLONE_PATH/.git" -b "$branch"
|
||||
if git -C "$MUTTER_CLONE_PATH" config --unset core.bare; then
|
||||
git -C "$MUTTER_CLONE_PATH" checkout
|
||||
else
|
||||
# For some weird reasons sometimes the fast-path could fail with
|
||||
# "fatal: not in a git directory" error, so handle it manually
|
||||
tmpdir=$(mktemp --directory --tmpdir mutter-XXXXXX)
|
||||
mkdir "$tmpdir/repo"
|
||||
mv "$MUTTER_CLONE_PATH/.git" "$tmpdir/repo/"
|
||||
git clone "$tmpdir/repo" "$tmpdir/src"
|
||||
mv "$tmpdir"/src/* "$tmpdir"/src/.* "$MUTTER_CLONE_PATH"
|
||||
rm -r "$tmpdir/repo"
|
||||
rm -rv "$tmpdir"
|
||||
fi
|
||||
fi
|
||||
set +x
|
||||
fi
|
||||
|
||||
.mutter.skip-git-clone:
|
||||
extends:
|
||||
- .skip-git-clone
|
||||
variables:
|
||||
MUTTER_CLONE_PATH: ''
|
||||
|
||||
.mutter.run-as-user:
|
||||
image:
|
||||
name: ${FDO_DISTRIBUTION_IMAGE}
|
||||
entrypoint:
|
||||
- 'runuser'
|
||||
- '-u'
|
||||
- !reference [.mutter.fedora@common, variables, MUTTER_USER]
|
||||
- '--'
|
||||
|
||||
.mutter.distribution-image:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
- .mutter.run-as-user
|
||||
|
||||
.mutter.fedora@common:
|
||||
extends:
|
||||
- .skip-git-clone
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: 41
|
||||
BASE_TAG: '2025-03-28.0'
|
||||
MUTTER_USER: 'meta-user'
|
||||
FDO_DISTRIBUTION_PACKAGES:
|
||||
accountsservice-devel
|
||||
clang
|
||||
gcovr
|
||||
gnome-shell
|
||||
itstool
|
||||
python3-docutils
|
||||
sassc
|
||||
uncrustify
|
||||
xorg-x11-server-Xvfb
|
||||
mesa-dri-drivers
|
||||
mesa-vulkan-drivers
|
||||
xorg-x11-proto-devel
|
||||
qemu-system-x86-core
|
||||
busybox
|
||||
zenity
|
||||
python3-dbusmock
|
||||
gnome-desktop-testing
|
||||
ruff
|
||||
mypy
|
||||
|
||||
FDO_DISTRIBUTION_EXEC: |
|
||||
set -e
|
||||
|
||||
# Create $MUTTER_USER
|
||||
useradd -u 9999 -b /opt/mutter -ms /bin/bash $MUTTER_USER
|
||||
|
||||
# Enable sudo for $MUTTER_USER
|
||||
echo "%$MUTTER_USER ALL = (ALL) NOPASSWD: ALL" > /etc/sudoers.d/99_mutter-user
|
||||
|
||||
# Drop problematic vulkan driver that interferes with CI;
|
||||
# see https://gitlab.gnome.org/GNOME/gtk/-/commit/7814d1fd75911
|
||||
rm /usr/share/vulkan/icd.d/powervr_mesa_icd.x86_64.json
|
||||
|
||||
dnf install -y 'dnf-command(builddep)'
|
||||
|
||||
dnf builddep -y mutter --setopt=install_weak_deps=False
|
||||
dnf builddep -y gnome-shell --setopt=install_weak_deps=False
|
||||
dnf builddep -y kernel --setopt=install_weak_deps=False
|
||||
dnf builddep -y gi-docgen --setopt=install_weak_deps=False
|
||||
dnf builddep -y wayland --setopt=install_weak_deps=False
|
||||
|
||||
./.gitlab-ci/install-meson-project.sh \
|
||||
https://gitlab.gnome.org/jadahl/catch.git \
|
||||
main
|
||||
|
||||
./.gitlab-ci/install-meson-project.sh \
|
||||
https://gitlab.gnome.org/GNOME/gi-docgen.git \
|
||||
main
|
||||
|
||||
./.gitlab-ci/install-common-dependencies.sh
|
||||
|
||||
rpm -e --nodeps gnome-bluetooth-libs-devel \
|
||||
mutter mutter-devel \
|
||||
gnome-shell \
|
||||
$NULL
|
||||
|
||||
# Work-around for podman-push aborting on permission issue
|
||||
# https://gitlab.gnome.org/Infrastructure/Infrastructure/-/issues/1247
|
||||
rm -rf /etc/pki/pesign/
|
||||
chmod -R a+rX /opt/mutter/$MUTTER_USER
|
||||
chmod -R a+rX /var/lib/gdm
|
||||
|
||||
# Ensure that we mark the project clone dir as safe directory
|
||||
git config --system --add safe.directory "$CI_PROJECT_DIR"
|
||||
|
||||
if [[ x"$(uname -m )" = "xx86_64" ]] ; then
|
||||
# deprecated header no longer included in openssl-devel
|
||||
dnf install -y openssl-devel-engine
|
||||
|
||||
if [ -n "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" ]; then
|
||||
git clone --depth $MUTTER_CLONE_DEPTH \
|
||||
$CI_MERGE_REQUEST_SOURCE_PROJECT_URL.git mutter-src \
|
||||
-b "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"
|
||||
elif [ -n "$CI_COMMIT_BRANCH" ]; then
|
||||
git clone --depth $MUTTER_CLONE_DEPTH \
|
||||
$CI_REPOSITORY_URL mutter-src -b "$CI_COMMIT_BRANCH"
|
||||
else
|
||||
git clone --depth $MUTTER_CLONE_DEPTH $CI_REPOSITORY_URL mutter-src
|
||||
fi
|
||||
meson setup build mutter-src -Dkvm_tests=true
|
||||
ninja -C build src/tests/kvm/bzImage
|
||||
mkdir -p /opt/mutter
|
||||
cp build/src/tests/kvm/bzImage /opt/mutter/bzImage
|
||||
|
||||
git clone https://github.com/arighi/virtme-ng.git
|
||||
cd virtme-ng
|
||||
git fetch --tags
|
||||
git checkout v1.8
|
||||
./setup.py install --prefix=/usr
|
||||
cd ..
|
||||
rm -rf virtme-ng
|
||||
rm -rf build mutter-src
|
||||
fi
|
||||
retry:
|
||||
max: 2
|
||||
when:
|
||||
- 'always'
|
||||
|
||||
default:
|
||||
# Cancel jobs if newer commits are pushed to the branch
|
||||
interruptible: true
|
||||
# Auto-retry jobs in case of infra failures
|
||||
retry:
|
||||
max: 1
|
||||
when:
|
||||
- 'runner_system_failure'
|
||||
- 'stuck_or_timeout_failure'
|
||||
- 'scheduler_failure'
|
||||
- 'api_failure'
|
||||
|
||||
.mutter.fedora@x86_64:
|
||||
extends:
|
||||
- .mutter.fedora@common
|
||||
- .mutter.git-clone
|
||||
variables:
|
||||
FDO_DISTRIBUTION_TAG: "x86_64-${BASE_TAG}"
|
||||
|
||||
.mutter.fedora@aarch64:
|
||||
extends:
|
||||
- .mutter.fedora@common
|
||||
- .mutter.git-clone
|
||||
variables:
|
||||
FDO_DISTRIBUTION_TAG: "aarch64-${BASE_TAG}"
|
||||
tags:
|
||||
- aarch64
|
||||
|
||||
workflow:
|
||||
rules:
|
||||
# Allow to switch from branch pipelines to MR pipelines seamlessly
|
||||
# https://docs.gitlab.com/ee/ci/jobs/job_control.html#avoid-duplicate-pipelines
|
||||
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
# Don't trigger a branch pipeline if there is an open MR
|
||||
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
|
||||
when: never
|
||||
- if: '$CI_COMMIT_BRANCH'
|
||||
- if: '$CI_COMMIT_TAG'
|
||||
|
||||
.pipeline-guard:
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
- if: '$CI_COMMIT_TAG'
|
||||
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
||||
- if: '$CI_COMMIT_BRANCH =~ /^gnome-[0-9-]+$/'
|
||||
# Avoid catchall `when: manual` rule which might
|
||||
# cause duplicate pipelines to be triggered.
|
||||
# https://docs.gitlab.com/ee/ci/jobs/job_control.html#avoid-duplicate-pipelines
|
||||
#
|
||||
# Also make it so pipelines without MR need to be started
|
||||
# manually, since their state will most likely be WIP
|
||||
- if: '$CI_COMMIT_BRANCH'
|
||||
when: 'manual'
|
||||
|
||||
.only-merge-requests:
|
||||
rules:
|
||||
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^$/'
|
||||
when: never
|
||||
- if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
|
||||
when: on_success
|
||||
|
||||
repo-sanity:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
stage: review
|
||||
variables:
|
||||
GIT_DEPTH: "1"
|
||||
script:
|
||||
- >
|
||||
if [[ -z "$CI_REGISTRY_IMAGE" ]] ;
|
||||
then
|
||||
.gitlab-ci/simple-junit-report.sh check-junit-report.xml \
|
||||
repo-sanity "The container registry should be enabled in the project general settings panel at $CI_PROJECT_URL/edit" ;
|
||||
exit 1 ;
|
||||
fi
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- check-junit-report.xml
|
||||
reports:
|
||||
junit: check-junit-report.xml
|
||||
rules:
|
||||
- !reference [.only-merge-requests, rules]
|
||||
|
||||
check-commit-log:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
stage: review
|
||||
variables:
|
||||
GIT_DEPTH: "100"
|
||||
script:
|
||||
ci-fairy check-commits --junit-xml=commit-message-junit-report.xml
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- commit-message-junit-report.xml
|
||||
reports:
|
||||
junit: commit-message-junit-report.xml
|
||||
rules:
|
||||
- !reference [.only-merge-requests, rules]
|
||||
- ./.gitlab-ci/check-commit-log.sh
|
||||
only:
|
||||
- merge_requests
|
||||
|
||||
check-merge-request:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
- .skip-git-clone
|
||||
stage: review
|
||||
script:
|
||||
ci-fairy check-merge-request --require-allow-collaboration --junit-xml=check-merge-request-report.xml
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- check-merge-request-report.xml
|
||||
reports:
|
||||
junit: check-merge-request-report.xml
|
||||
rules:
|
||||
- !reference [.only-merge-requests, rules]
|
||||
|
||||
build-fedora-container@x86_64:
|
||||
extends:
|
||||
- .fdo.container-build@fedora@x86_64
|
||||
- .mutter.fedora@x86_64
|
||||
- .mutter.skip-git-clone
|
||||
stage: prepare
|
||||
rules:
|
||||
- !reference [.pipeline-guard, rules]
|
||||
|
||||
build-fedora-container@aarch64:
|
||||
extends:
|
||||
- .fdo.container-build@fedora@aarch64
|
||||
- .mutter.fedora@aarch64
|
||||
- .mutter.skip-git-clone
|
||||
stage: prepare
|
||||
rules:
|
||||
- !reference [.pipeline-guard, rules]
|
||||
when: manual
|
||||
|
||||
check-c-code-style:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
variables:
|
||||
MUTTER_CLONE_DEPTH: 200
|
||||
stage: code-review
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
script:
|
||||
git config --global --add safe.directory $CI_PROJECT_DIR ;
|
||||
git remote add target $CI_MERGE_REQUEST_PROJECT_URL.git ;
|
||||
git fetch target $CI_MERGE_REQUEST_TARGET_BRANCH_NAME ;
|
||||
export common_parent_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "target/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME") <(git rev-list --first-parent HEAD) | head -1) ;
|
||||
python3 -u ./check-style.py --dry-run --sha $common_parent_sha ;
|
||||
allow_failure: true
|
||||
rules:
|
||||
- !reference [.only-merge-requests, rules]
|
||||
|
||||
check-python-code-style:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
variables:
|
||||
PYTHON_FILES:
|
||||
tools/gdctl
|
||||
clutter/clutter/gen-keyname-table.py
|
||||
clutter/clutter/clutter-keysyms-update.py
|
||||
stage: code-review
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
script:
|
||||
- ruff format --line-length 80 --check $PYTHON_FILES
|
||||
- ruff check $PYTHON_FILES
|
||||
- mypy $PYTHON_FILES
|
||||
rules:
|
||||
- !reference [.only-merge-requests, rules]
|
||||
|
||||
.build-mutter-base:
|
||||
variables:
|
||||
BASE_MESON_OPTIONS:
|
||||
-Degl_device=true
|
||||
-Dwayland_eglstream=true
|
||||
-Dcatch=true
|
||||
|
||||
.build-mutter:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .build-mutter-base
|
||||
build-mutter:
|
||||
stage: build
|
||||
script:
|
||||
- meson setup . build
|
||||
--prefix /usr
|
||||
--werror
|
||||
--fatal-meson-warnings
|
||||
--warnlevel 2
|
||||
--wrap-mode nofallback
|
||||
-Dbuildtype=debugoptimized
|
||||
-Db_coverage=true
|
||||
-Ddocs=true
|
||||
$BASE_MESON_OPTIONS
|
||||
$EXTRA_MESON_OPTIONS
|
||||
- meson compile -C build
|
||||
- sudo meson install --dry-run -C build
|
||||
- meson . build -Dbuildtype=debugoptimized -Degl_device=true -Dwayland_eglstream=true --werror --prefix /usr
|
||||
- ninja -C build
|
||||
- ninja -C build install
|
||||
artifacts:
|
||||
expire_in: 1 day
|
||||
paths:
|
||||
- build
|
||||
only:
|
||||
- merge_requests
|
||||
- /^.*$/
|
||||
|
||||
build-mutter@x86_64:
|
||||
variables:
|
||||
EXTRA_MESON_OPTIONS:
|
||||
-Dkvm_tests=true
|
||||
-Dkvm_kernel_image=/opt/mutter/bzImage
|
||||
extends:
|
||||
- .build-mutter
|
||||
- .mutter.fedora@x86_64
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
|
||||
build-mutter@aarch64:
|
||||
extends:
|
||||
- .build-mutter
|
||||
- .mutter.fedora@aarch64
|
||||
needs:
|
||||
- job: build-fedora-container@aarch64
|
||||
artifacts: false
|
||||
when: manual
|
||||
|
||||
build-without-opengl-and-glx@x86_64:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
stage: build
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
script:
|
||||
- meson setup . build
|
||||
--prefix /usr
|
||||
--werror
|
||||
--wrap-mode nofallback
|
||||
-Dbuildtype=debugoptimized
|
||||
-Dopengl=false
|
||||
-Dglx=false
|
||||
-Degl_device=true
|
||||
-Dwayland_eglstream=true
|
||||
-Dintrospection=false
|
||||
- meson compile -C build
|
||||
- sudo meson install --no-rebuild -C build
|
||||
artifacts:
|
||||
paths:
|
||||
- build/meson-logs
|
||||
|
||||
build-without-native-backend-and-wayland@x86_64:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
stage: build
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
script:
|
||||
- meson setup . build
|
||||
--prefix /usr
|
||||
--werror
|
||||
--wrap-mode nofallback
|
||||
-Dbuildtype=debugoptimized
|
||||
-Dnative_backend=false
|
||||
-Dudev=false
|
||||
-Dwayland=false
|
||||
-Dxwayland=false
|
||||
-Dtests=disabled
|
||||
-Dintrospection=false
|
||||
- meson compile -C build
|
||||
- sudo meson install --no-rebuild -C build
|
||||
artifacts:
|
||||
paths:
|
||||
- build/meson-logs
|
||||
|
||||
build-wayland-xwayland@x86_64:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
stage: build
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
script:
|
||||
- meson setup . build
|
||||
--prefix /usr
|
||||
--werror
|
||||
--wrap-mode nofallback
|
||||
-Dbuildtype=debugoptimized
|
||||
-Dwayland=true
|
||||
-Dxwayland=true
|
||||
-Dx11=false
|
||||
-Dtests=disabled
|
||||
-Dintrospection=false
|
||||
- meson compile -C build
|
||||
- sudo meson install --no-rebuild -C build
|
||||
artifacts:
|
||||
paths:
|
||||
- build/meson-logs
|
||||
|
||||
build-wayland-only@x86_64:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
stage: build
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
script:
|
||||
- meson setup . build
|
||||
--prefix /usr
|
||||
--werror
|
||||
--wrap-mode nofallback
|
||||
-Dbuildtype=debugoptimized
|
||||
-Dwayland=true
|
||||
-Dxwayland=false
|
||||
-Dx11=false
|
||||
-Dtests=disabled
|
||||
-Dintrospection=false
|
||||
- meson compile -C build
|
||||
- sudo meson install --no-rebuild -C build
|
||||
artifacts:
|
||||
paths:
|
||||
- build/meson-logs
|
||||
|
||||
.test-setup:
|
||||
test-mutter:
|
||||
stage: test
|
||||
dependencies:
|
||||
- build-mutter
|
||||
variables:
|
||||
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
|
||||
GSETTINGS_SCHEMA_DIR: "$CI_PROJECT_DIR/build/data"
|
||||
MUTTER_DEBUG_DUMMY_MODE_SPECS: "800x600@10.0"
|
||||
PIPEWIRE_DEBUG: 2
|
||||
PIPEWIRE_LOG: "$CI_PROJECT_DIR/build/meson-logs/pipewire.log"
|
||||
XVFB_SERVER_ARGS: "+iglx -noreset"
|
||||
G_SLICE: "always-malloc"
|
||||
MALLOC_CHECK_: "3"
|
||||
NO_AT_BRIDGE: "1"
|
||||
GTK_A11Y: "none"
|
||||
before_script:
|
||||
- !reference [.mutter.git-clone, before_script]
|
||||
|
||||
.test-mutter-base:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .test-setup
|
||||
stage: test
|
||||
after_script:
|
||||
- pushd build
|
||||
- gcovr --root=..
|
||||
--filter='\.\./src/'
|
||||
--filter='\.\./clutter/'
|
||||
--filter='\.\./cogl/'
|
||||
--filter='\.\./mtk/'
|
||||
--gcov-ignore-errors=no_working_dir_found
|
||||
--exclude='\.\./build/.*\.[ch]$' --exclude='.*/tests/.*\.[ch]$'
|
||||
--json --output=../coverage-${CI_JOB_NAME}.json
|
||||
- popd
|
||||
artifacts:
|
||||
expire_in: 1 day
|
||||
name: "mutter-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
|
||||
when: always
|
||||
paths:
|
||||
- build
|
||||
- coverage-*.json
|
||||
|
||||
.test-mutter:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .test-mutter-base
|
||||
script:
|
||||
- mkdir -m 700 $XDG_RUNTIME_DIR
|
||||
- glib-compile-schemas $GSETTINGS_SCHEMA_DIR
|
||||
- mkdir -m 1777 /tmp/.X11-unix
|
||||
- ./src/tests/meta-dbus-runner.py
|
||||
--
|
||||
meson test
|
||||
-C build
|
||||
--setup plain
|
||||
--no-suite 'mutter/kvm'
|
||||
--no-suite 'gvdb'
|
||||
--no-rebuild
|
||||
--timeout-multiplier 10
|
||||
--print-errorlogs
|
||||
artifacts:
|
||||
reports:
|
||||
junit: "build/meson-logs/testlog-plain.junit.xml"
|
||||
- >
|
||||
env MALLOC_PERTURB_="$((RANDOM % 256 + 1))"
|
||||
dbus-run-session -- xvfb-run -s '+iglx -noreset'
|
||||
meson test -C build --no-rebuild -t 10 --verbose --no-stdsplit --wrap catchsegv
|
||||
only:
|
||||
- merge_requests
|
||||
- /^.*$/
|
||||
|
||||
test-mutter@x86_64:
|
||||
extends:
|
||||
- .mutter.fedora@x86_64
|
||||
- .test-mutter
|
||||
tags:
|
||||
- asan
|
||||
needs:
|
||||
- build-mutter@x86_64
|
||||
|
||||
test-mutter-kvm@x86_64:
|
||||
extends:
|
||||
- .mutter.fedora@x86_64
|
||||
- .test-mutter-base
|
||||
tags:
|
||||
- kvm
|
||||
script:
|
||||
- meson test -C build
|
||||
--no-rebuild
|
||||
--timeout-multiplier 10
|
||||
--setup plain
|
||||
--suite 'mutter/kvm'
|
||||
--print-errorlogs
|
||||
needs:
|
||||
- build-mutter@x86_64
|
||||
artifacts:
|
||||
reports:
|
||||
junit: "build/meson-logs/testlog-plain.junit.xml"
|
||||
|
||||
test-mutter@aarch64:
|
||||
extends:
|
||||
- .mutter.fedora@aarch64
|
||||
- .test-mutter
|
||||
tags:
|
||||
- asan-aarch64
|
||||
needs:
|
||||
- build-mutter@aarch64
|
||||
when: manual
|
||||
|
||||
coverage:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
stage: analyze
|
||||
script:
|
||||
- compgen -G "coverage-*.json" > /dev/null || exit 0
|
||||
- mkdir coveragereport
|
||||
- gcovr --add-tracefile 'coverage-*.json'
|
||||
--html-details
|
||||
--html-theme github.blue
|
||||
--print-summary
|
||||
--output coveragereport/index.html
|
||||
- gcovr --add-tracefile 'coverage-*.json'
|
||||
--xml --output coveragereport/coverage.xml
|
||||
artifacts:
|
||||
expose_as: 'Coverage Report'
|
||||
paths:
|
||||
- coveragereport
|
||||
- coveragereport/index.html
|
||||
reports:
|
||||
coverage_report:
|
||||
coverage_format: cobertura
|
||||
# TODO: we may need to split this file once it will reach the
|
||||
# gitlab limit size of 10M, or it will stop working:
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/328772
|
||||
path: coveragereport/coverage.xml
|
||||
coverage: '/^lines: (\d+\.\d+\%)/'
|
||||
needs:
|
||||
- test-mutter@x86_64
|
||||
# - test-mutter@aarch64
|
||||
- test-mutter-kvm@x86_64
|
||||
|
||||
can-run-gnome-shell@x86_64:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
- .test-setup
|
||||
can-build-gnome-shell:
|
||||
stage: test
|
||||
needs:
|
||||
- build-mutter@x86_64
|
||||
dependencies:
|
||||
- build-mutter
|
||||
before_script:
|
||||
- !reference [.mutter.fedora@x86_64, before_script]
|
||||
- sudo meson install --no-rebuild -C build
|
||||
- meson install --no-rebuild -C build
|
||||
script:
|
||||
- .gitlab-ci/checkout-gnome-shell.sh
|
||||
- meson setup gnome-shell gnome-shell/build --prefix /usr -Dbuildtype=debugoptimized -Dman=false --werror --fatal-meson-warnings
|
||||
- sudo meson install -C gnome-shell/build
|
||||
- mkdir -m 1777 /tmp/.X11-unix
|
||||
- dbus-run-session -- meson test -C gnome-shell/build --no-rebuild --timeout-multiplier 5
|
||||
artifacts:
|
||||
expire_in: 7 day
|
||||
name: "mutter-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
|
||||
when: on_failure
|
||||
paths:
|
||||
- gnome-shell/build/meson-logs
|
||||
|
||||
test-mutter-coverity:
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "schedule" && $MUTTER_SCHEDULED_JOB == "coverity"'
|
||||
when: on_success
|
||||
- if: '$CI_COMMIT_BRANCH'
|
||||
when: 'manual'
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
stage: analyze
|
||||
allow_failure: true
|
||||
script:
|
||||
- .gitlab-ci/download-coverity-tarball.sh
|
||||
- CC=clang meson setup coverity-build -Dprofiler=false
|
||||
- ./coverity/cov-analysis-linux64-*/bin/cov-build --dir cov-int meson compile -C coverity-build
|
||||
- tar czf cov-int.tar.gz cov-int
|
||||
- curl https://scan.coverity.com/builds?project=mutter
|
||||
--form token=$COVERITY_TOKEN --form email=carlosg@gnome.org
|
||||
--form file=@cov-int.tar.gz --form version="`git describe --tags`"
|
||||
--form description="GitLab CI build"
|
||||
cache:
|
||||
key: coverity-tarball
|
||||
paths:
|
||||
- coverity
|
||||
|
||||
dist-mutter:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
- .mutter.fedora@x86_64
|
||||
- .build-mutter-base
|
||||
- .test-setup
|
||||
stage: deploy
|
||||
needs:
|
||||
- job: build-fedora-container@x86_64
|
||||
artifacts: false
|
||||
script:
|
||||
- meson setup . build
|
||||
--prefix /usr
|
||||
--werror
|
||||
--wrap-mode nofallback
|
||||
-Dbuildtype=debugoptimized
|
||||
- glib-compile-schemas $GSETTINGS_SCHEMA_DIR
|
||||
- mkdir -m 1777 /tmp/.X11-unix
|
||||
- ./src/tests/meta-dbus-runner.py
|
||||
--
|
||||
meson dist -C build --include-subprojects
|
||||
artifacts:
|
||||
expire_in: 7 day
|
||||
name: "mutter-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
|
||||
when: always
|
||||
paths:
|
||||
- build/meson-private/dist-build/meson-logs
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE != "merge_request_event"'
|
||||
when: manual
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
changes:
|
||||
- "**/meson.build"
|
||||
- meson/*
|
||||
when: on_success
|
||||
- if: '$GITLAB_USER_LOGIN == "marge-bot"'
|
||||
when: on_success
|
||||
- if: '$CI_MERGE_REQUEST_ASSIGNEES == "marge-bot"'
|
||||
when: on_success
|
||||
|
||||
installed-tests-mutter@x86_64:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
- .mutter.fedora@x86_64
|
||||
- .build-mutter-base
|
||||
- .test-setup
|
||||
stage: deploy
|
||||
needs:
|
||||
- build-mutter@x86_64
|
||||
script:
|
||||
- meson install -C build --no-rebuild
|
||||
- mkdir -m 1777 /tmp/.X11-unix
|
||||
- mkdir installed-tests-logs
|
||||
- gnome-desktop-testing-runner -L installed-tests-logs mutter
|
||||
artifacts:
|
||||
expire_in: 7 day
|
||||
name: "mutter-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
|
||||
when: always
|
||||
paths:
|
||||
- installed-tests-logs
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE != "merge_request_event"'
|
||||
when: manual
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
changes:
|
||||
- "**/meson.build"
|
||||
- meson/*
|
||||
when: on_success
|
||||
- if: '$GITLAB_USER_LOGIN == "marge-bot"'
|
||||
when: on_success
|
||||
- if: '$CI_MERGE_REQUEST_ASSIGNEES == "marge-bot"'
|
||||
when: on_success
|
||||
|
||||
dist-mutter-tarball:
|
||||
extends: dist-mutter
|
||||
artifacts:
|
||||
expose_as: 'Get tarball here'
|
||||
name: "${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
|
||||
when: always
|
||||
paths:
|
||||
- $TARBALL_ARTIFACT_PATH
|
||||
rules:
|
||||
- if: '$CI_COMMIT_TAG'
|
||||
|
||||
reference:
|
||||
extends:
|
||||
- .mutter.distribution-image
|
||||
- .mutter.fedora@x86_64
|
||||
stage: docs
|
||||
needs:
|
||||
- build-mutter@x86_64
|
||||
script:
|
||||
- mkdir references
|
||||
- cp -r doc/website/* ./references
|
||||
- mv build/doc/reference/{clutter/clutter,cogl/cogl,meta/meta,mtk/mtk} references/
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
expose_as: 'Documentation'
|
||||
paths:
|
||||
- references/
|
||||
|
||||
pages:
|
||||
stage: deploy
|
||||
needs: ['reference']
|
||||
extends:
|
||||
- .skip-git-clone
|
||||
script:
|
||||
- mv references public/
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
rules:
|
||||
- if: ($CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH && $CI_PROJECT_NAMESPACE == "GNOME")
|
||||
- meson gnome-shell gnome-shell/build --prefix /usr
|
||||
- ninja -C gnome-shell/build install
|
||||
only:
|
||||
- merge_requests
|
||||
- /^.*$/
|
||||
|
||||
26
.gitlab-ci/Dockerfile
Normal file
26
.gitlab-ci/Dockerfile
Normal file
@@ -0,0 +1,26 @@
|
||||
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 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 && \
|
||||
|
||||
# For running unit tests
|
||||
dnf install -y xorg-x11-server-Xvfb mesa-dri-drivers dbus dbus-x11 '*/xvfb-run' gdm-lib accountsservice-libs && \
|
||||
|
||||
# Unpackaged versions
|
||||
dnf install -y https://copr-be.cloud.fedoraproject.org/results/jadahl/mutter-ci/fedora-29-x86_64/00834984-gsettings-desktop-schemas/gsettings-desktop-schemas-3.30.1-1.20181206git918efdd69be53.fc29.x86_64.rpm https://copr-be.cloud.fedoraproject.org/results/jadahl/mutter-ci/fedora-29-x86_64/00834984-gsettings-desktop-schemas/gsettings-desktop-schemas-devel-3.30.1-1.20181206git918efdd69be53.fc29.x86_64.rpm && \
|
||||
|
||||
dnf install -y intltool redhat-rpm-config make && \
|
||||
|
||||
# GNOME Shell
|
||||
dnf builddep -y gnome-shell --setopt=install_weak_deps=False && \
|
||||
dnf remove -y gnome-bluetooth-libs-devel dbus-glib-devel upower-devel python3-devel && \
|
||||
dnf remove -y --noautoremove mutter mutter-devel && \
|
||||
|
||||
dnf clean all
|
||||
57
.gitlab-ci/check-commit-log.sh
Executable file
57
.gitlab-ci/check-commit-log.sh
Executable 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
|
||||
@@ -1,19 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
fetch() {
|
||||
local remote=$1
|
||||
local ref=$2
|
||||
|
||||
git fetch --quiet --depth=1 $remote $ref 2>/dev/null
|
||||
}
|
||||
#!/usr/bin/bash
|
||||
|
||||
mutter_branch=$(git describe --contains --all HEAD)
|
||||
gnome_shell_target=
|
||||
|
||||
echo -n Cloning into gnome-shell ...
|
||||
if git clone --quiet --depth=1 https://gitlab.gnome.org/GNOME/gnome-shell.git; then
|
||||
echo \ done
|
||||
else
|
||||
echo \ failed
|
||||
git clone https://gitlab.gnome.org/GNOME/gnome-shell.git
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo Checkout failed
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -23,34 +16,20 @@ if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
|
||||
merge_request_remote=${CI_MERGE_REQUEST_SOURCE_PROJECT_URL//mutter/gnome-shell}
|
||||
merge_request_branch=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
|
||||
|
||||
echo -n Looking for $merge_request_branch on remote ...
|
||||
if fetch $merge_request_remote $merge_request_branch; then
|
||||
echo \ found
|
||||
echo Looking for $merge_request_branch on remote ...
|
||||
if git fetch -q $merge_request_remote $merge_request_branch 2>/dev/null; then
|
||||
gnome_shell_target=FETCH_HEAD
|
||||
else
|
||||
echo \ not found
|
||||
|
||||
echo -n Looking for $CI_MERGE_REQUEST_TARGET_BRANCH_NAME instead ...
|
||||
if fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME; then
|
||||
echo \ found
|
||||
gnome_shell_target=FETCH_HEAD
|
||||
else
|
||||
echo \ not found
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$gnome_shell_target" ]; then
|
||||
ref_remote=${CI_PROJECT_URL//mutter/gnome-shell}
|
||||
echo -n Looking for $CI_COMMIT_REF_NAME on remote ...
|
||||
if fetch $ref_remote $CI_COMMIT_REF_NAME; then
|
||||
echo \ found
|
||||
gnome_shell_target=FETCH_HEAD
|
||||
else
|
||||
echo \ not found
|
||||
gnome_shell_target=HEAD
|
||||
gnome_shell_target=origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
|
||||
echo Using $gnome_shell_target instead
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$gnome_shell_target" ]; then
|
||||
gnome_shell_target=$(git branch -r -l origin/$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
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
patterns:
|
||||
deny:
|
||||
- regex: '^$CI_MERGE_REQUEST_PROJECT_URL/(-/)?merge_requests/$CI_MERGE_REQUEST_IID$'
|
||||
message: Commit message must not contain a link to its own merge request
|
||||
- regex: '^(meta-|Meta)'
|
||||
message: Commit message subject should not be prefixed with 'meta-' or 'Meta'
|
||||
where: subject
|
||||
- regex: '^(clutter-|Clutter)'
|
||||
message: Commit message subject should not be prefixed with 'clutter-' or 'Clutter', use 'clutter/' instead
|
||||
where: subject
|
||||
- regex: '^(cogl-|Cogl)'
|
||||
message: Commit message subject should not be prefixed with 'cogl-' or 'Cogl', use 'cogl/' instead
|
||||
where: subject
|
||||
- regex: '^[^:]+: [a-z]'
|
||||
message: "Commit message subject should be properly Capitalized. E.g. 'window: Marginalize extradicity'"
|
||||
where: subject
|
||||
- regex: '^\S*\.[ch]:'
|
||||
message: Commit message subject prefix should not include .c, .h, etc.
|
||||
where: subject
|
||||
- regex: '^[Cc]lose[sd]?:?\s*#[0-9]+'
|
||||
message: Closes instructions must be a full link
|
||||
- regex: '^[Ff]ix(e[sd]?)?:?\s*(#[0-9]+|https://)'
|
||||
message: \"Fixes\" should be used with commits, use \"Closes\" for issues
|
||||
@@ -1,38 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# We need a coverity token to fetch the tarball
|
||||
if [ -x $COVERITY_TOKEN ]
|
||||
then
|
||||
echo "No coverity token. Run this job from a protected branch."
|
||||
exit -1
|
||||
fi
|
||||
|
||||
mkdir -p coverity
|
||||
|
||||
# Download and check MD5 first
|
||||
curl https://scan.coverity.com/download/linux64 \
|
||||
--data "token=$COVERITY_TOKEN&project=mutter&md5=1" \
|
||||
--output /tmp/coverity_tool.md5
|
||||
|
||||
diff /tmp/coverity_tool.md5 coverity/coverity_tool.md5 >/dev/null 2>&1
|
||||
|
||||
if [ $? -eq 0 -a -d coverity/cov-analysis* ]
|
||||
then
|
||||
echo "Coverity tarball is up-to-date"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Download and extract coverity tarball
|
||||
curl https://scan.coverity.com/download/linux64 \
|
||||
--data "token=$COVERITY_TOKEN&project=mutter" \
|
||||
--output /tmp/coverity_tool.tgz
|
||||
|
||||
rm -rf ./coverity/cov-analysis*
|
||||
|
||||
tar zxf /tmp/coverity_tool.tgz -C coverity/
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
mv /tmp/coverity_tool.md5 coverity/
|
||||
fi
|
||||
|
||||
rm /tmp/coverity_tool.tgz
|
||||
@@ -1,167 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
usage() {
|
||||
cat <<-EOF
|
||||
Usage: $(basename $0) [OPTION…]
|
||||
|
||||
Install common dependencies to a base image or system extension
|
||||
|
||||
Options:
|
||||
--libdir=DIR Setup the projects with a different libdir
|
||||
--destdir=DIR Install the project to DIR, can be used
|
||||
several times to install to multiple destdirs
|
||||
|
||||
-h, --help Display this help
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
pkgconf() {
|
||||
local PKG_CONFIG_DIRS=(
|
||||
/usr/lib64/pkgconfig
|
||||
/usr/lib/pkgconfig
|
||||
/usr/share/pkgconfig
|
||||
)
|
||||
|
||||
local search_dirs=()
|
||||
for destdir in "${DESTDIRS[@]}"; do
|
||||
search_dirs+=( "${PKG_CONFIG_DIRS[@]/#/$destdir}" )
|
||||
done
|
||||
|
||||
ENV=(PKG_CONFIG_PATH=$(echo "${search_dirs[@]}" | tr ' ' :))
|
||||
|
||||
env "${ENV[@]}" pkgconf --env-only "$@"
|
||||
}
|
||||
|
||||
pip_install() {
|
||||
local pkg=$1
|
||||
|
||||
for destdir in "${DESTDIRS[@]}"; do
|
||||
local pypaths=($destdir/usr/lib*/python3*/site-packages)
|
||||
if ! pip3 list "${pypaths[@]/#/--path=}" | grep $pkg >/dev/null
|
||||
then
|
||||
sudo pip3 install --ignore-installed \
|
||||
--root-user-action ignore \
|
||||
--prefix $destdir/usr \
|
||||
$pkg
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
check_gsettings_key() {
|
||||
local schema=$1
|
||||
local key=$2
|
||||
|
||||
local rv=0
|
||||
|
||||
for destdir in "${DESTDIRS[@]}"; do
|
||||
local schemadir=$(realpath $destdir/usr/share/glib-2.0/schemas/)
|
||||
local targetdir=$(mktemp --directory)
|
||||
|
||||
if ! glib-compile-schemas --targetdir $targetdir $schemadir 2>/dev/null ||\
|
||||
! env -i "XDG_DATA_DIRS=/dev/null" \
|
||||
gsettings --schemadir $targetdir get $schema $key >/dev/null 2>&1
|
||||
then
|
||||
rv=1
|
||||
fi
|
||||
|
||||
rm -rf $targetdir
|
||||
done
|
||||
|
||||
return $rv
|
||||
}
|
||||
|
||||
TEMP=$(getopt \
|
||||
--name=$(basename $0) \
|
||||
--options='h' \
|
||||
--longoptions='libdir:' \
|
||||
--longoptions='destdir:' \
|
||||
--longoptions='help' \
|
||||
-- "$@")
|
||||
|
||||
eval set -- "$TEMP"
|
||||
unset TEMP
|
||||
|
||||
OPTIONS=()
|
||||
DESTDIRS=()
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
--libdir)
|
||||
OPTIONS+=( --libdir=$2 )
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--destdir)
|
||||
DESTDIRS+=( $2 )
|
||||
shift 2
|
||||
;;
|
||||
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ ${#DESTDIRS[@]} == 0 ]] && DESTDIRS+=( / )
|
||||
OPTIONS+=( "${DESTDIRS[@]/#/--destdir=}" )
|
||||
|
||||
SCRIPTS_DIR="$(dirname $0)"
|
||||
|
||||
if ! pkgconf --atleast-version 48.alpha gsettings-desktop-schemas
|
||||
then
|
||||
./$SCRIPTS_DIR/install-meson-project.sh \
|
||||
"${OPTIONS[@]}" \
|
||||
https://gitlab.gnome.org/GNOME/gsettings-desktop-schemas.git \
|
||||
master
|
||||
fi
|
||||
|
||||
if ! pkgconf --atleast-version 1.3.901 libeis-1.0
|
||||
then
|
||||
./$SCRIPTS_DIR/install-meson-project.sh \
|
||||
"${OPTIONS[@]}" \
|
||||
https://gitlab.freedesktop.org/libinput/libei.git \
|
||||
1.3.901
|
||||
fi
|
||||
|
||||
pip_install argcomplete
|
||||
|
||||
if ! check_gsettings_key org.gnome.login-screen banner-message-source
|
||||
then
|
||||
./$SCRIPTS_DIR/install-meson-project.sh \
|
||||
"${OPTIONS[@]}" \
|
||||
https://gitlab.gnome.org/GNOME/gdm.git \
|
||||
main
|
||||
fi
|
||||
|
||||
if ! pkgconf --atleast-version 1.83.4 gjs-1.0
|
||||
then
|
||||
./$SCRIPTS_DIR/install-meson-project.sh \
|
||||
"${OPTIONS[@]}" \
|
||||
https://gitlab.gnome.org/GNOME/gjs.git \
|
||||
master
|
||||
fi
|
||||
|
||||
if ! pkgconf --atleast-version 1.41 wayland-protocols
|
||||
then
|
||||
./$SCRIPTS_DIR/install-meson-project.sh \
|
||||
"${OPTIONS[@]}" \
|
||||
https://gitlab.freedesktop.org/wayland/wayland-protocols.git \
|
||||
1.41
|
||||
fi
|
||||
|
||||
if ! pkgconf --atleast-version 1.8.0 libxkbcommon
|
||||
then
|
||||
./$SCRIPTS_DIR/install-meson-project.sh \
|
||||
"${OPTIONS[@]}" \
|
||||
https://github.com/xkbcommon/libxkbcommon.git \
|
||||
master
|
||||
fi
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPTS_DIR="$(dirname $0)"
|
||||
|
||||
# Location for dependencies to be bundled with the extension
|
||||
DESTDIR="$(realpath $1)"
|
||||
|
||||
# GNOME OS specific setup arguments
|
||||
LIBDIR="lib/$(gcc -print-multiarch)"
|
||||
|
||||
# Install common dependencies
|
||||
./$SCRIPTS_DIR/install-common-dependencies.sh --libdir=$LIBDIR --destdir=$DESTDIR --destdir=/
|
||||
|
||||
# Install below missing dependencies that are exclusive to GNOME OS
|
||||
|
||||
./$SCRIPTS_DIR/install-meson-project.sh \
|
||||
--libdir=$LIBDIR --destdir=$DESTDIR --destdir=/ \
|
||||
https://gitlab.gnome.org/GNOME/zenity.git \
|
||||
master
|
||||
@@ -1,107 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
usage() {
|
||||
cat <<-EOF
|
||||
Usage: $(basename $0) [OPTION…] REPO_URL COMMIT
|
||||
|
||||
Check out and install a meson project
|
||||
|
||||
Options:
|
||||
-Dkey=val Option to pass on to meson
|
||||
--subdir=DIR Build subdirectory instead of whole project
|
||||
--prepare=SCRIPT Script to run before build
|
||||
--libdir=DIR Setup the project with a different libdir
|
||||
--destdir=DIR Install the project to DIR, can be used
|
||||
several times to install to multiple destdirs
|
||||
|
||||
-h, --help Display this help
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
TEMP=$(getopt \
|
||||
--name=$(basename $0) \
|
||||
--options='D:h' \
|
||||
--longoptions='subdir:' \
|
||||
--longoptions='prepare:' \
|
||||
--longoptions='libdir:' \
|
||||
--longoptions='destdir:' \
|
||||
--longoptions='help' \
|
||||
-- "$@")
|
||||
|
||||
eval set -- "$TEMP"
|
||||
unset TEMP
|
||||
|
||||
MESON_OPTIONS=()
|
||||
SUBDIR=.
|
||||
PREPARE=:
|
||||
DESTDIRS=()
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
-D)
|
||||
MESON_OPTIONS+=( -D$2 )
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--subdir)
|
||||
SUBDIR=$2
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--prepare)
|
||||
PREPARE=$2
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--libdir)
|
||||
MESON_OPTIONS+=( --libdir=$2 )
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--destdir)
|
||||
DESTDIRS+=( $2 )
|
||||
shift 2
|
||||
;;
|
||||
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $# -lt 2 ]]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
REPO_URL="$1"
|
||||
COMMIT="$2"
|
||||
|
||||
[[ ${#DESTDIRS[@]} == 0 ]] && DESTDIRS+=( / )
|
||||
|
||||
CHECKOUT_DIR=$(mktemp --directory)
|
||||
trap "rm -rf $CHECKOUT_DIR" EXIT
|
||||
|
||||
git clone --depth 1 "$REPO_URL" -b "$COMMIT" "$CHECKOUT_DIR"
|
||||
|
||||
pushd "$CHECKOUT_DIR/$SUBDIR"
|
||||
sh -c "$PREPARE"
|
||||
meson setup --prefix=/usr _build "${MESON_OPTIONS[@]}"
|
||||
|
||||
# Install it to all specified dest dirs
|
||||
for destdir in "${DESTDIRS[@]}"; do
|
||||
# don't use --destdir when installing to root,
|
||||
# so post-install hooks are run
|
||||
[[ $destdir == / ]] && destdir=
|
||||
sudo meson install -C _build ${destdir:+--destdir=$destdir}
|
||||
done
|
||||
popd
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
OUTFILE=$1
|
||||
NAME=$2
|
||||
MESSAGE=$3
|
||||
|
||||
cat >$OUTFILE <<EOF
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<testsuites tests="1" errors="0" failures="1">
|
||||
<testsuite name="repo-sanity" tests="1" errors="0" failures="1">
|
||||
<testcase name="$NAME" classname="repo-sanity">
|
||||
<failure message="$MESSAGE"/>
|
||||
</testcase>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
EOF
|
||||
|
||||
# Also echo the message in stdout for good measure
|
||||
echo $MESSAGE
|
||||
@@ -1,55 +0,0 @@
|
||||
<!--
|
||||
Please read https://handbook.gnome.org/issues/reporting.html
|
||||
first to ensure that you create a clear and specific issue.
|
||||
-->
|
||||
|
||||
### Affected version
|
||||
|
||||
<!--
|
||||
Provide at least the following information:
|
||||
* Your OS and version
|
||||
* Affected Mutter version
|
||||
* Does this issue appear in XOrg and/or Wayland
|
||||
-->
|
||||
|
||||
### Bug summary
|
||||
|
||||
<!--
|
||||
Provide a short summary of the bug you encountered.
|
||||
-->
|
||||
|
||||
### Steps to reproduce
|
||||
|
||||
<!--
|
||||
1. Step one
|
||||
2. Step two
|
||||
3. ...
|
||||
-->
|
||||
|
||||
### What happened
|
||||
|
||||
<!--
|
||||
What did Mutter do that was unexpected?
|
||||
-->
|
||||
|
||||
### What did you expect to happen
|
||||
|
||||
<!--
|
||||
What did you expect Mutter to do?
|
||||
-->
|
||||
|
||||
### Relevant logs, screenshots, screencasts etc.
|
||||
|
||||
<!--
|
||||
If you have further information, such as technical documentation, logs,
|
||||
screenshots or screencasts related, please provide them here.
|
||||
|
||||
If the bug is a crash, please obtain a stack trace with installed debug
|
||||
symbols (at least for GNOME Shell and Mutter) and attach it to
|
||||
this issue following the instructions on
|
||||
https://handbook.gnome.org/issues/stack-traces.html.
|
||||
-->
|
||||
|
||||
|
||||
<!-- Do not remove the following line. -->
|
||||
/label ~"1. Bug"
|
||||
@@ -1,30 +0,0 @@
|
||||
<!--
|
||||
Please read https://handbook.gnome.org/issues/reporting.html
|
||||
first to ensure that you create a clear and specific issue.
|
||||
-->
|
||||
|
||||
### Feature summary
|
||||
|
||||
<!--
|
||||
Describe what you would like to be able to do with Mutter
|
||||
that you currently cannot do.
|
||||
-->
|
||||
|
||||
### How would you like it to work
|
||||
|
||||
<!--
|
||||
If you can think of a way Mutter might be able to do this,
|
||||
let us know here.
|
||||
-->
|
||||
|
||||
### Relevant links, screenshots, screencasts etc.
|
||||
|
||||
<!--
|
||||
If you have further information, such as technical documentation,
|
||||
code, mockups or a similar feature in another window managers,
|
||||
please provide them here.
|
||||
-->
|
||||
|
||||
|
||||
<!-- Do not remove the following line. -->
|
||||
/label ~"1. Feature"
|
||||
34
README.md
34
README.md
@@ -14,7 +14,7 @@ window compositing, focus tracking, workspace management, keybindings and
|
||||
monitor configuration.
|
||||
|
||||
Internally it uses a fork of Cogl, a hardware acceleration abstraction library
|
||||
used to simplify usage of OpenGL pipelines, as well as a fork of Clutter, a
|
||||
used to simplify usage of OpenGL pipelines, as well as a fork af Clutter, a
|
||||
scene graph and user interface toolkit.
|
||||
|
||||
Mutter is used by, for example, GNOME Shell, the GNOME core user interface, and
|
||||
@@ -26,31 +26,15 @@ debugging purposes.
|
||||
|
||||
To contribute, open merge requests at https://gitlab.gnome.org/GNOME/mutter.
|
||||
|
||||
It can be useful to first look at the
|
||||
[GNOME Handbook](https://handbook.gnome.org/development.html) and the
|
||||
documentation and API references below first.
|
||||
The coding style used is primarily the GNU flavor of the [GNOME coding
|
||||
style](https://developer.gnome.org/programming-guidelines/stable/c-coding-style.html.en)
|
||||
with some minor additions such as preferring `stdint.h` types over GLib
|
||||
fundamental types, and a soft 80 character line limit. However, in general,
|
||||
look at the file you're editing for inspiration.
|
||||
|
||||
## Documentation
|
||||
|
||||
- [Coding style and conventions](doc/coding-style.md)
|
||||
- [Git conventions](doc/git-conventions.md)
|
||||
- [Code overview](doc/code-overview.md)
|
||||
- [Building and Running](doc/building-and-running.md)
|
||||
- [Debugging](doc/debugging.md)
|
||||
- [Monitor configuration](doc/monitor-configuration.md)
|
||||
- [Multi-GPU](doc/multi-gpu.md)
|
||||
|
||||
## API Reference
|
||||
|
||||
- Meta: <https://mutter.gnome.org/meta/>
|
||||
- Clutter: <https://mutter.gnome.org/clutter/>
|
||||
- Cogl: <https://mutter.gnome.org/cogl/>
|
||||
- Mtk: <https://mutter.gnome.org/mtk/>
|
||||
|
||||
## Meetings
|
||||
|
||||
There are [recurring meetings](https://hedgedoc.gnome.org/s/ymP_L5MUs) to
|
||||
discuss development of GNOME Shell, mutter and related components.
|
||||
Commit messages should follow the [GNOME commit message
|
||||
guidelines](https://wiki.gnome.org/Git/CommitMessages). We require an URL
|
||||
to either an issue or a merge request in each commit.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
164
check-style.py
164
check-style.py
@@ -1,164 +0,0 @@
|
||||
#!/bin/env python3
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
# Path relative to this script
|
||||
uncrustify_cfg = 'tools/uncrustify.cfg'
|
||||
|
||||
def run_diff(sha):
|
||||
proc = subprocess.run(
|
||||
["git", "diff", "-U0", "--function-context", "--default-prefix", sha, "HEAD"],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
encoding="utf-8",
|
||||
)
|
||||
return proc.stdout.strip().splitlines()
|
||||
|
||||
def find_chunks(diff):
|
||||
file_entry_re = re.compile(r'^\+\+\+ b/(.*)$')
|
||||
diff_chunk_re = re.compile(r'^@@ -\d+,\d+ \+(\d+),(\d+)')
|
||||
file = None
|
||||
chunks = []
|
||||
|
||||
for line in diff:
|
||||
match = file_entry_re.match(line)
|
||||
if match:
|
||||
file = match.group(1)
|
||||
|
||||
match = diff_chunk_re.match(line)
|
||||
if match:
|
||||
start = int(match.group(1))
|
||||
len = int(match.group(2))
|
||||
end = start + len
|
||||
|
||||
if len > 0 and (file.endswith('.c') or file.endswith('.h') or file.endswith('.vala')):
|
||||
chunks.append({ 'file': file, 'start': start, 'end': end })
|
||||
|
||||
return chunks
|
||||
|
||||
def reformat_chunks(chunks, rewrite):
|
||||
# Creates temp file with INDENT-ON/OFF comments
|
||||
def create_temp_file(file, start, end):
|
||||
with open(file) as f:
|
||||
tmp = tempfile.NamedTemporaryFile()
|
||||
if start > 1:
|
||||
tmp.write(b'/** *INDENT-OFF* **/\n')
|
||||
for i, line in enumerate(f, start=1):
|
||||
if i == start - 1:
|
||||
tmp.write(b'/** *INDENT-ON* **/\n')
|
||||
|
||||
tmp.write(bytes(line, 'utf-8'))
|
||||
|
||||
if i == end - 1:
|
||||
tmp.write(b'/** *INDENT-OFF* **/\n')
|
||||
|
||||
tmp.seek(0)
|
||||
|
||||
return tmp
|
||||
|
||||
# Removes uncrustify INDENT-ON/OFF helper comments
|
||||
def remove_indent_comments(output):
|
||||
tmp = tempfile.NamedTemporaryFile()
|
||||
|
||||
for line in output:
|
||||
if line != b'/** *INDENT-OFF* **/\n' and line != b'/** *INDENT-ON* **/\n':
|
||||
tmp.write(line)
|
||||
|
||||
tmp.seek(0)
|
||||
|
||||
return tmp
|
||||
|
||||
changed = None
|
||||
|
||||
for chunk in chunks:
|
||||
# Add INDENT-ON/OFF comments
|
||||
tmp = create_temp_file(chunk['file'], chunk['start'], chunk['end'])
|
||||
|
||||
# uncrustify chunk
|
||||
proc = subprocess.run(
|
||||
["uncrustify", "-c", uncrustify_cfg, "-f", tmp.name],
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
reindented = proc.stdout.splitlines(keepends=True)
|
||||
if proc.returncode != 0:
|
||||
continue
|
||||
|
||||
tmp.close()
|
||||
|
||||
# Remove INDENT-ON/OFF comments
|
||||
formatted = remove_indent_comments(reindented)
|
||||
|
||||
if dry_run is True:
|
||||
# Show changes
|
||||
proc = subprocess.run(
|
||||
["diff", "-up", "--color=always", chunk['file'], formatted.name],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
encoding="utf-8",
|
||||
)
|
||||
diff = proc.stdout
|
||||
if diff != '':
|
||||
output = re.sub('\t', '↦\t', diff)
|
||||
print(output)
|
||||
changed = True
|
||||
else:
|
||||
# Apply changes
|
||||
diff = subprocess.run(
|
||||
["diff", "-up", chunk['file'], formatted.name],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
)
|
||||
patch = subprocess.run(["patch", chunk['file']], input=diff.stdout)
|
||||
|
||||
formatted.close()
|
||||
|
||||
return changed
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description='Check code style. Needs uncrustify installed.')
|
||||
parser.add_argument('--sha', metavar='SHA', type=str,
|
||||
help='SHA for the commit to compare HEAD with')
|
||||
parser.add_argument('--dry-run', '-d', type=bool,
|
||||
action=argparse.BooleanOptionalAction,
|
||||
help='Only print changes to stdout, do not change code')
|
||||
parser.add_argument('--rewrite', '-r', type=bool,
|
||||
action=argparse.BooleanOptionalAction,
|
||||
help='Whether to amend the result to the last commit (e.g. \'git rebase --exec "%(prog)s -r"\')')
|
||||
|
||||
# Change CWD to script location, necessary for always locating the configuration file
|
||||
os.chdir(os.path.dirname(os.path.abspath(sys.argv[0])))
|
||||
|
||||
args = parser.parse_args()
|
||||
sha = args.sha or 'HEAD^'
|
||||
rewrite = args.rewrite
|
||||
dry_run = args.dry_run
|
||||
|
||||
diff = run_diff(sha)
|
||||
chunks = find_chunks(diff)
|
||||
changed = reformat_chunks(chunks, rewrite)
|
||||
|
||||
if dry_run is not True and rewrite is True:
|
||||
proc = subprocess.run(["git", "add", "-p"])
|
||||
if proc.returncode == 0:
|
||||
# Commit the added changes as a squash commit
|
||||
subprocess.run(
|
||||
["git", "commit", "--squash", "HEAD", "-C", "HEAD"],
|
||||
stdout=subprocess.DEVNULL)
|
||||
# Delete the unapplied changes
|
||||
subprocess.run(["git", "reset", "--hard"], stdout=subprocess.DEVNULL)
|
||||
os._exit(0)
|
||||
elif dry_run is True and changed is True:
|
||||
print(f"""
|
||||
Issue the following commands in your local tree to apply the suggested changes:
|
||||
|
||||
$ git rebase {sha} --exec "./check-style.py -r"
|
||||
$ git rebase --autosquash {sha}
|
||||
""")
|
||||
os._exit(-1)
|
||||
|
||||
os._exit(0)
|
||||
95
clutter/.gitignore
vendored
Normal file
95
clutter/.gitignore
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
ABOUT-NLS
|
||||
INSTALL
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
compile
|
||||
*.pc
|
||||
.deps
|
||||
.libs
|
||||
*.o
|
||||
*.lo
|
||||
*.la
|
||||
*.gcov
|
||||
.dirstamp
|
||||
README
|
||||
stamp-enum-types
|
||||
stamp-marshal
|
||||
tags
|
||||
/ChangeLog*
|
||||
clutter-build-config.h
|
||||
clutter-build-config.h.in
|
||||
clutter-config.h
|
||||
clutter-enum-types.[ch]
|
||||
clutter-marshal.[ch]
|
||||
gcov-report.txt
|
||||
clutter-json.h
|
||||
clutter-lcov.info
|
||||
clutter-lcov
|
||||
!/build/autotools/introspection.m4
|
||||
!/build/autotools/as-linguas.m4
|
||||
!/build/autotools/as-compiler-flag.m4
|
||||
!/build/autotools/glibtests.m4
|
||||
/build/autotools/*.m4
|
||||
/build/test-driver
|
||||
*.gir
|
||||
*.typelib
|
||||
*.gcda
|
||||
*.gcno
|
||||
config.*
|
||||
configure
|
||||
depcomp
|
||||
/doc/cookbook/*.pdf
|
||||
/doc/cookbook/html
|
||||
/doc/cookbook/*.stamp
|
||||
/doc/cookbook/clutter-cookbook.xml
|
||||
/doc/cookbook/clutter-cookbook.html
|
||||
doc/reference/clutter-*.txt
|
||||
!/doc/reference/clutter-sections.txt
|
||||
doc/reference/html
|
||||
doc/reference/tmpl
|
||||
doc/reference/xml
|
||||
doc/reference/clutter.args
|
||||
doc/reference/clutter.hierarchy
|
||||
doc/reference/clutter.interfaces
|
||||
doc/reference/clutter.prerequisites
|
||||
doc/reference/clutter.signals
|
||||
doc/reference/clutter-docs.xml
|
||||
doc/reference/*.stamp
|
||||
doc/reference/*.bak
|
||||
doc/reference/*.log
|
||||
doc/reference/gtkdoc-check.*
|
||||
gtk-doc.make
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
mkinstalldirs
|
||||
stamp-h1
|
||||
TAGS
|
||||
/tests/tools/disable-npots.sh
|
||||
/tests/conform/test-launcher.sh
|
||||
/tests/interactive/wrapper.sh
|
||||
/po/POTFILES
|
||||
/po/clutter-1.0.pot
|
||||
/po/*.gmo
|
||||
/po/Makefile.in.in
|
||||
/po/Makevars.template
|
||||
/po/Rules-quot
|
||||
/po/boldquot.sed
|
||||
/po/en@boldquot.header
|
||||
/po/en@quot.header
|
||||
/po/insert-header.sin
|
||||
/po/quot.sed
|
||||
/po/remove-potcdate.sin
|
||||
/po/remove-potcdate.sed
|
||||
/po/stamp-po
|
||||
*.swn
|
||||
*.swo
|
||||
*.swp
|
||||
*~
|
||||
*.orig
|
||||
*.rej
|
||||
.DS_Store
|
||||
.testlogs-*
|
||||
986
clutter/clutter/cally/ChangeLog.pre-cally-merge
Normal file
986
clutter/clutter/cally/ChangeLog.pre-cally-merge
Normal file
@@ -0,0 +1,986 @@
|
||||
# DO NOT MODIFY THIS FILE
|
||||
#
|
||||
# Clutter uses the Git commit log to generate the ChangeLog files when
|
||||
# creating the tarball for releases and snapshots. This file is maintained
|
||||
# only for historical reasons.
|
||||
|
||||
2010-07-05 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Cleaning ClutterText
|
||||
|
||||
* Removing superfluous g_return_if_fail
|
||||
* Removing unused ClutterText::text-changed callback
|
||||
|
||||
2010-07-05 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Refactoring "window:create" and "window:destroy" emission code
|
||||
|
||||
Previously "window:create" and "window:destroy" were emitted on
|
||||
CallyUtil. Although it works, and CallyUtil already have callbacks to
|
||||
stage_added/removed signals, I think that it is more tidy/clear to do
|
||||
that on CallyRoot:
|
||||
|
||||
* CallyRoot already has code to manage ClutterStage addition/removal
|
||||
|
||||
* In fact, we can see CallyRoot as the object exposing the a11y
|
||||
information from ClutterStageManager, so it fits better here.
|
||||
|
||||
* CallyUtil callbacks these signals are related to key event
|
||||
listeners (key snooper simulation). One of the main CallyUtil
|
||||
responsabilities is managing event (connecting, emitting), so I
|
||||
would prefer to not start to add/mix more functionalities here.
|
||||
|
||||
Ideally it would be better to emit all CallyStage methods from
|
||||
CallyStage, but it is clear that "create" and "destroy" are more easy
|
||||
to emit from a external object.
|
||||
|
||||
2010-06-25 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Cleaning clutter-actor
|
||||
|
||||
Some cleaning changes:
|
||||
* Using CallyActionFunc instead of ACTION_FUNC
|
||||
* Removing a extra * on cally-actor-private macro documentation, to
|
||||
avoid gtk-doc warnings
|
||||
* Using g_strcmp0 instead of strcmp
|
||||
|
||||
Changes to be applied on clutter (see CB#2097 and CB#2098), applied
|
||||
also here to maintain the sync. My intention is keep this developing line
|
||||
until the real integration, in order to make a final independent cally
|
||||
release.
|
||||
|
||||
2010-06-14 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Adding -Wshadow option and solving warnings related
|
||||
|
||||
|
||||
2010-06-14 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Added dummy padding for future vt expasion
|
||||
|
||||
Added dummy padding on the different classes structures, to allow
|
||||
future expansion of virtual methods.
|
||||
|
||||
I decided to add this on all the classes, although it would be
|
||||
really unlikely in some cases (ie, CallyGroup)
|
||||
|
||||
2010-06-10 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Adding and emitting "window:xxx" methods on CallyStage
|
||||
|
||||
Added some window related signals on CallyStage:
|
||||
|
||||
* window:activate and window:deactivate emitted from CallyStage
|
||||
* window:create and window:destroy emitted from CallyUtil
|
||||
|
||||
ClutterStage doesn't fulfill 100% the window concept, but some of
|
||||
these signals are important in order to identify the object which
|
||||
could emit global/key events.
|
||||
|
||||
The current implementation is equivalent to GailWindow one, supposing
|
||||
CallyStage as the only window related window. This likely would change
|
||||
in any clutter-based toolkit implement a real Window object, so a more
|
||||
flexible procedure would be required. But we would solve problems step
|
||||
by step.
|
||||
|
||||
BTW: as I explain here [1] I really think that the current way to
|
||||
implement "window:xxx" signals (not defined in ATK but expected from
|
||||
the a11y implementation toolkit) somewhat hacky and undocumented (you
|
||||
need to check at-spi2 idls to know that you require to emit this
|
||||
events)
|
||||
|
||||
Related to bug CB#2147 (Orca doesn't speech out properly non
|
||||
printable chars on some environments), as solves this problem
|
||||
in a specific case.
|
||||
|
||||
[1] https://bugzilla.gnome.org/show_bug.cgi?id=620977#c1
|
||||
|
||||
2010-06-04 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Avoiding clutter_stage_get_key_focus warning
|
||||
|
||||
For any reason, in some cases, a clutter actor doesn't have a stage
|
||||
associated. We use the default one as fallback.
|
||||
|
||||
2010-06-02 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Added a defunct check on cally_group_get_n_children
|
||||
|
||||
Some warnings appeared when we tried to get the number
|
||||
of children of a defunct object.
|
||||
|
||||
2010-06-02 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Update TODO file
|
||||
|
||||
Use Bugzilla to setting missing features.
|
||||
|
||||
2010-06-01 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Removing heuristics to decide CallyRectable/CallyTexture role
|
||||
|
||||
Previously CallyRectangle and CallyTexture used some heuristics in
|
||||
order to decide the default role: ATK_ROLE_IMAGE or
|
||||
ATK_PUSH_BUTTON, as in practice most applications using these
|
||||
objects as buttons were not applying the proper role.
|
||||
|
||||
As this is a hack, and a application responsibility, finally we
|
||||
have decided to remove this, so the default role is ATK_ROLE_IMAGE.
|
||||
|
||||
Fixes CB#1732 (CallyTexture and CallyRectangle uses some heuristics to
|
||||
decide the role)
|
||||
|
||||
2010-05-28 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Post-release version bump, after release 1.2.0
|
||||
|
||||
I wrongly added the last commit on the 1.1 branch, when in fact it
|
||||
requires clutter 1.3.3, and on the README it is explained that
|
||||
cally versioning is tied to clutter versioning. In order to solve
|
||||
that a clutter-1.2 release branch is created, and bumped the version.
|
||||
|
||||
This versioning tyding will be obsolete when the integration with
|
||||
clutter become a reality, but in the same way, this is the way to
|
||||
tidy this thinking in this integration.
|
||||
|
||||
2010-04-13 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Use clutter_actor_get_accessible
|
||||
|
||||
The method clutter_actor_get_accessible was added due work on
|
||||
bug 2070, and should be used to get the accessibility object,
|
||||
instead of atk_gobject_accessible_for_object
|
||||
|
||||
This would allow to implement a11y support directly on
|
||||
any clutter based toolkit object (ie StLabel).
|
||||
|
||||
2010-05-13 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Added CallyClone example
|
||||
|
||||
|
||||
2010-05-13 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Added a11y support for ClutterClone
|
||||
|
||||
Resolved in the most simplified way, just as a image and a
|
||||
default description to identify cloned objects.
|
||||
|
||||
More information:
|
||||
http://lists.o-hand.com/clutter/3797.html
|
||||
|
||||
2010-04-14 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Remove gail dependency
|
||||
|
||||
Removed to avoid gdk/gtk dependency on cally.
|
||||
|
||||
Part of bug CB#2072 solution
|
||||
|
||||
2010-04-14 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Avoid gdk functions filling AtkKeyEventStruct
|
||||
|
||||
Now when AtkKeyEventStruct is filled in order to emit any key event
|
||||
signal, it is not used any gdk function on the keyval or the
|
||||
string fields.
|
||||
|
||||
event_string is filled with the printable character if possible, if
|
||||
not (Ctrl, Alt, etc) it is set as NULL.
|
||||
|
||||
Now the AT should take care of that, at least until we define atk key
|
||||
event struct in a more agnostic way (not tied to gdk/gtk). See orca
|
||||
bug bgo#616206 as a example.
|
||||
|
||||
Part of bug CB#2072 solution.
|
||||
|
||||
2010-04-15 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Added gail_misc_layout_get_run_attributes implementation
|
||||
|
||||
Part of bug CB#2072 solution
|
||||
|
||||
2010-04-14 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Remove gailutil/gailmisc functions calls
|
||||
|
||||
This is because gailutil/gailmisc added a gdk/gtk dependency, and
|
||||
this dependency is being removed. New cally-specific implementation
|
||||
are required.
|
||||
|
||||
Related to bug CB#1733
|
||||
|
||||
Part of bug CB#2072 solution
|
||||
|
||||
2010-04-13 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Fixing the libdir directory in some examples
|
||||
|
||||
|
||||
2010-03-26 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Previous cally.pc.in update was incomplete
|
||||
|
||||
The previous commit was not tested properly, and it was missing one
|
||||
detail. Sorry for the noise.
|
||||
|
||||
2010-03-26 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Update cally.pc.in after module relocation
|
||||
|
||||
Previous commit places cally module in a different directory.
|
||||
It also corrects where the include directory is placed.
|
||||
|
||||
2010-03-15 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Use a proper clutter module directory
|
||||
|
||||
Use a proper clutter module directory, instead of keep being
|
||||
installed on a gtk directory.
|
||||
|
||||
Improve the cally-examples-util, in order to keep using
|
||||
hardcoded values.
|
||||
|
||||
Fixes CB#1737 (Wrong cally module directory)
|
||||
|
||||
2010-03-15 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Proper UTF-8 headers
|
||||
|
||||
|
||||
2010-02-25 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Change "--with-dbus" option for "atk-bridge-dir" on examples
|
||||
|
||||
The atk-adaptor in the dbus at-spi was renamed to atk-bridge due
|
||||
some apps hardcoding the name. So right now the only difference
|
||||
is the final directory.
|
||||
|
||||
So the option was removed, and atk-bridge-dir added. This also allows
|
||||
to use the system atk-bridge or the compiled in any developing environment,
|
||||
so it is really more flexible.
|
||||
|
||||
See the README (updated with this commit) for more information.
|
||||
|
||||
2010-02-19 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Added .gitignore file
|
||||
|
||||
|
||||
2010-02-19 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Release 1.1.1
|
||||
|
||||
|
||||
2010-02-19 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Using clutter_threads_idle_add instead of the gdk one
|
||||
|
||||
The idea is being as less gdk dependent as possible. Right now
|
||||
it is inviable to remove the dependency (gailutil and so on) but
|
||||
hypothetically, the ideal is remove this dependency in the future,
|
||||
and being "clutter pure".
|
||||
|
||||
2010-02-15 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Check if the state is defunct on cally_text_get_name
|
||||
|
||||
Check if the state is defunct on cally_text_get_name, in order
|
||||
to avoid warnings cally clutter_text_get_text when the clutter
|
||||
object is NULL
|
||||
|
||||
2010-01-26 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Update on configure.ac after autoupdate call
|
||||
|
||||
|
||||
2010-02-02 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Try to apply the key modifiers to event->keyval like GDK does
|
||||
|
||||
ClutterKeyEvent defines the keyval without taking into account the
|
||||
modifiers. GDK defines this keyval taking into account the modifiers.
|
||||
|
||||
AtkKeyEventStruct expects the keyval in a GDK fashion, so a
|
||||
translation is required.
|
||||
|
||||
This patch tries to do that using using
|
||||
gdk_keymap_translate_keyboard_state.
|
||||
|
||||
This functions only works correctly if gtk has been initialized, so
|
||||
the fallback is create the AtkKeyEventStruct with the keyval
|
||||
provided by Clutter.
|
||||
|
||||
More information:
|
||||
http://library.gnome.org/devel/atk/stable/AtkUtil.html#AtkKeyEventStruct
|
||||
http://bugzilla.openedhand.com/show_bug.cgi?id=1961
|
||||
|
||||
2010-02-02 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Filling AtkKeyEventStruct->string used on the atk key event listeners
|
||||
|
||||
Finally we use directly gdk_keyval_name. Not the ideal solution, but works,
|
||||
and more important, it avoids to reimplement this issue on clutter or cally.
|
||||
|
||||
More information on Bug 1952
|
||||
|
||||
Fixes http://bugzilla.openedhand.com/show_bug.cgi?id=1952
|
||||
|
||||
2010-01-22 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Added AM_PROG_CC_C_O option to avoid a warning running configure
|
||||
|
||||
|
||||
2010-01-22 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Fix clutter version required on the pc files
|
||||
|
||||
|
||||
2010-01-22 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Check on configure time if any x11 clutter backend is in use
|
||||
|
||||
It uses AC_CHECK_LIB in order to check if x11 backend is in use.
|
||||
It also modifies cally-actor in order to use the information
|
||||
retrieved.
|
||||
|
||||
So now cally has a minimum multi-backend support. It only manages
|
||||
a x11 (glx or eglx) backend, but at least, it checks it, so you
|
||||
can compile cally without this backend. It probably will not work
|
||||
properly, but at least you can compile and execute it.
|
||||
|
||||
Solves http://bugzilla.openedhand.com/show_bug.cgi?id=1736
|
||||
|
||||
2010-01-21 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Fix the perspective problems computing the on-screen extensions
|
||||
|
||||
Use clutter_actor_get_abs_allocation_vertices and
|
||||
clutter_actor_get_transformed_size to get the real on-screen
|
||||
position and size, instead of compute that using the geometry
|
||||
and the anchor point.
|
||||
|
||||
It also update cally-atkcomponent-example, adding a actor inside
|
||||
a nested ClutterGroup hierarchy.
|
||||
|
||||
Fixes: http://bugzilla.openedhand.com/show_bug.cgi?id=1731
|
||||
|
||||
2010-01-13 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Added extra button on cally-atkeditabletext-example
|
||||
|
||||
Added a button to print the current cursor position, and also
|
||||
extend the size of the buttons
|
||||
|
||||
2010-01-12 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Remove superfluous g_print on CallyStage
|
||||
|
||||
|
||||
2009-12-03 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Use clutter_stage_manager_peek_stages to avoid a leak
|
||||
|
||||
|
||||
2009-12-03 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Added ATK_STATE_SELECTABLE_TEXT management
|
||||
|
||||
|
||||
2009-11-26 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Manage properly ATK_STATE_ACTIVE on CallyStage
|
||||
|
||||
* cally/cally-stage.c
|
||||
Added private struct
|
||||
(cally_stage_class_init),(cally_stage_init),(cally_stage_real_initalize):
|
||||
Initialization stuff
|
||||
(cally_stage_activate_cb)
|
||||
(cally_stage_deactivate_cb): new ClutterStage signal callbacks, change
|
||||
the internal value of active, and notify the atk state change
|
||||
(cally_stage_ref_state_set): manage ATK_STATE_ACTIVATE
|
||||
* examples/cally-atktext-example2.c
|
||||
If possible, creates two stage, in order to test ATK_STATE_ACTIVATE
|
||||
|
||||
2009-11-24 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Focused state change and focused object notification
|
||||
|
||||
* cally/cally-actor.h
|
||||
(focus_clutter): added virtual method for the focus management
|
||||
* cally/cally-actor.c
|
||||
(cally_actor_component_interface_init)
|
||||
(cally_actor_add_focus_handler)
|
||||
(cally_actor_remove_focus_handler):
|
||||
Implementation of the AtkComponent methods add_focus_handler and
|
||||
remove_focus_handler
|
||||
(cally_actor_focus_event): CallyActor specific focus handler, notify
|
||||
the state focused change
|
||||
(cally_actor_focus_clutter)
|
||||
(cally_actor_real_focus_clutter):
|
||||
Handlers for the ClutterActor "key-focus-in" and "key-focus-out"
|
||||
signals. Emit the signal AtkObject "focus_event" and set the focus
|
||||
object with atk_focus_tracker_notify.
|
||||
(cally_actor_initialize):
|
||||
Connect to the signals "key-focus-in" and "key-focus-out", use
|
||||
atk_component_add_focus_handler to add cally_actor_focus_event
|
||||
|
||||
Note: The focus management is more simplified that the gail one. The
|
||||
main reason is that the focus management in GTK is really more complex
|
||||
that the Clutter one.
|
||||
|
||||
2009-11-24 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Modify cally-atkeditabletext-example.c to manage "activatable" status
|
||||
|
||||
|
||||
2009-11-24 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Added "activate" action in ClutterText
|
||||
|
||||
* cally/cally-actor.h
|
||||
* cally/cally-actor.c
|
||||
cally_actor_add_action now returns the action id added. Documentation
|
||||
added in order to explain the return values and others.
|
||||
|
||||
* cally/cally-text.c
|
||||
Added action "activate". This action is only available if the ClutterText is
|
||||
activatable, so the "activatable" property is tracked in the notify
|
||||
|
||||
2009-11-20 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Signal event emission
|
||||
|
||||
Emits the signals "text_selection_changed", "text_caret_moved",
|
||||
"text_changed::insert", "text_changed::delete", and notify the
|
||||
ATK_STATE_EDITABLE state change.
|
||||
|
||||
It also adds the ATK_STATE_EDITABLE in the ref_state_set, includes a
|
||||
finalize to clean the new private data used, and move part of the
|
||||
initialization from the _init to the _real_initialization.
|
||||
|
||||
2009-12-03 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Remove the ATK_STATE_DEFUNCT emission
|
||||
|
||||
Remove the ATK_STATE_DEFUNCT emission, as this is already made by
|
||||
AtkGObjectAccessible.
|
||||
|
||||
It also removes the clutter actor from the private structure, as we
|
||||
can use the AtkGObjectAccessible API to obtain it. This makes the code
|
||||
more coherent, with respect of the rest of the Cally classes
|
||||
implementation.
|
||||
|
||||
2009-11-26 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Remove ; from the CALLY_GET_CLUTTER_ACTOR macro
|
||||
|
||||
|
||||
2009-11-25 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
TODO cleanup and more implementation notes
|
||||
|
||||
* TODO: removed the data that we have in the bugzilla or in the implementation
|
||||
notes on the cally source
|
||||
* cally/cally-actor.c: complete implementations notes
|
||||
* cally/Makefile.am: add a comment related to the public headers, and include
|
||||
Makefile.in in the MAINTAINERCLEANFILES
|
||||
|
||||
2009-11-13 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Adding new tips on CODING_STYLE
|
||||
|
||||
|
||||
2009-11-09 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
AtkEditableText implementation on CallyText
|
||||
|
||||
* examples/Makefile.am
|
||||
* examples/cally-atkeditabletext-example.c: New example added
|
||||
* cally/cally-text.c
|
||||
|
||||
Interface AtkEditableText implemented, except some methods:
|
||||
* Missing ClipBoard feature on Clutter:
|
||||
paste_text
|
||||
copy_text
|
||||
cut_text
|
||||
* Missing a equivalent GtkTextTag on Clutter (so the possibility to
|
||||
set run attributes in a range):
|
||||
set_run_attributes
|
||||
|
||||
Fixes bug CB#1734
|
||||
|
||||
2009-11-03 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Removed DG_DISABLE_CHECKS and DG_DISABLE_CAST_CHECKS from CFLAGS
|
||||
|
||||
* configure.ac: Removed DG_DISABLE_CHECKS and DG_DISABLE_CAST_CHECKS
|
||||
from the common CFLAGS options
|
||||
* cally/cally-actor.c: fixed cast errors on some return values, not
|
||||
detected previously because of the use of relaxed compilation
|
||||
options
|
||||
|
||||
Problem detected by Mario Sánchez Prada <msanchez@igalia.com>
|
||||
|
||||
2009-10-28 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Support for multiple stages
|
||||
|
||||
* cally-root.c
|
||||
* cally-stage.c
|
||||
* cally-util.c
|
||||
Implemented the support for multiple stages, by tracking the signals
|
||||
stage-added and stage-removed of the ClutterStageManager.
|
||||
|
||||
In the same way CallyRoot has implement properly the atk_object_initialize,
|
||||
and in general now is more tied to ClutterStageManager (CallyRoot is now
|
||||
the a11y object of ClutterStageManager), but factory not required anyway,
|
||||
as it is instanced on the CallyUtil atk_get_root
|
||||
|
||||
Fixes: CB#1754 (Missing multi-stage support)
|
||||
|
||||
2009-10-27 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Implemented atk_[add/remove]_key_event_listener on CallyUtil
|
||||
|
||||
* cally/cally-util.c:
|
||||
Implemented atk_[add/remove]_key_event_listener
|
||||
* examples/cally-atktext-example2.c:
|
||||
Modified in order to install and remove key event listeners,
|
||||
for testing purposes
|
||||
|
||||
Fixes CB#1852 (AtkUtil implementation misses
|
||||
atk_[add/remove]_key_event_listener)
|
||||
|
||||
2009-10-21 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Implemented atk-[add/remove]-global-event-listener on CallyUtil
|
||||
|
||||
* cally/cally-util.c:
|
||||
Implemented atk-[add/remove]-global-event-listener on CallyUtil
|
||||
* examples/Makefile.am
|
||||
* examples/cally-atktext-example2.c
|
||||
New example in order to test easier the event emission on focus
|
||||
change (not working right now)
|
||||
|
||||
2009-10-12 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Add --with-dbus option executing the examples
|
||||
|
||||
The replacement for atk-bridge on at-spi-dbus has a different name
|
||||
(atk-adaptor), and it has not defined the method gnome_accessibility_init.
|
||||
The --with-dbus option allow to load the correct library and use the
|
||||
correct hook method if you are using at-spi-dbus.
|
||||
|
||||
Anyway, take into account that this is just an example, and in a final
|
||||
environment, this should be made in a more general way.
|
||||
|
||||
More information: CB#1738, CB#1737
|
||||
|
||||
2009-09-25 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Symplifying shave support.
|
||||
|
||||
|
||||
2009-09-25 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Cleanup on the compilation and installation process
|
||||
|
||||
* cally/Makefile.am:
|
||||
Added libcallydir and libcally_HEADERS in order to publish all cally
|
||||
headers, as the current policy is use the cally headers as public.
|
||||
* configure.ac:
|
||||
Change API_VERSION_MAJOR for CALLY_API_VERSION, as was the real
|
||||
meaning, and define CALLY_VERSION.
|
||||
Change CALLY_OBJ_CFLAGS and CALLY_OBJ_LIBS, used to compile the
|
||||
tests, as was not required to compile against the cally module (the
|
||||
example only required to compile against Clutter, as the cally
|
||||
module was just a module loaded by GModule).
|
||||
Support for Shave.
|
||||
|
||||
2009-07-31 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Be able to run the examples without installing Cally
|
||||
|
||||
Before that, the examples searched the cally module from the final installed
|
||||
directory. This means that you should install the library to use the examples.
|
||||
On development this is not desirable. Now it is loaded from ../cally/.libs
|
||||
|
||||
This is a little hackish, but more useful, and in the end, it is just a example.
|
||||
Probably a best option could be configure that on the command line.
|
||||
$ ./example --cally-dir="mydir"
|
||||
|
||||
But just a nitpick.
|
||||
|
||||
2009-07-29 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Upgrade to cally-1.0, using clutter-1.0
|
||||
|
||||
* NEWS
|
||||
* TODO: removed several items, waiting to be moved to the bugzilla
|
||||
* configure.ac
|
||||
* examples/cally-examples-util.c
|
||||
|
||||
2009-07-27 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Fixed return value of cally_actor_get_index_in_parent
|
||||
|
||||
Bug and solutiond pointed by Gerd Kohlberger
|
||||
|
||||
2009-06-30 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Added the implementation of most AtkText methods for CluttetText (CallyText)
|
||||
|
||||
It remains some methods:
|
||||
get_default_attributes
|
||||
get_character_extents
|
||||
get_offset_at_point
|
||||
|
||||
The current gail implementation delegate on gailmisc, but this is tied to
|
||||
GtkWidget so an equivalent functionality would be implemented (something like
|
||||
callymisc), and in the case of get_character_extents, not sure about the layout
|
||||
position (see gtk_entry_get_layout_offsets).
|
||||
|
||||
I think that worth manage this in a different commit.
|
||||
|
||||
In the same way is still missing AtkEditableText support.
|
||||
|
||||
2009-07-07 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Added CALLY_GET_CLUTTER_ACTOR macro
|
||||
|
||||
This macro was created to simplify how do you get the clutter actor object
|
||||
related to the cally object. On CallyActor a private attributte maintains it
|
||||
(for convenience, as it is heavily used) but outside, atkgobject methods can
|
||||
be used. Note that there is a possibility on the future to change it. Two
|
||||
options:
|
||||
* Add a public method to get the clutter object
|
||||
* Use this method on CallyActor too
|
||||
|
||||
This macro simplifies this:
|
||||
|
||||
CLUTTER_ACTOR (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (cally_object)))
|
||||
|
||||
2009-06-24 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Renamed examples/cally-util.[ch] to examples/cally-examples-util.[ch]
|
||||
|
||||
Renamed examples/cally-util.[ch] to examples/cally-examples-util.[ch] to avoid
|
||||
confusion with cally/cally-util.[ch], implementation of the AtkUtil interface
|
||||
|
||||
2009-06-23 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Adding examples directory
|
||||
|
||||
* NEWS: Updates
|
||||
* configure.ac
|
||||
* Makefile.am
|
||||
* cally/Makefile.am
|
||||
* examples/Makefile.am: New
|
||||
* examples/cally-util.[ch]: New
|
||||
* examples/example1.c: New
|
||||
Added a directory in order to put examples. In this way we don't require any
|
||||
external clutter app to make the basic a11y functionality checks. At this
|
||||
moment only an example was added, but all the compiling structure is working.
|
||||
By default the examples are not compiled, use "--enable-examples" on configure
|
||||
time in order to enable their compilation.
|
||||
|
||||
This basic example basically shows several objects, with different depth, in
|
||||
order to check that AtkComponent returns the correct screen position.
|
||||
|
||||
Other minor changes done on the building infrastructure.
|
||||
|
||||
2009-06-23 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Fix clutter version required
|
||||
|
||||
|
||||
2009-06-23 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Solve a problem calling clutter_actor_get_anchor_point
|
||||
|
||||
* cally/cally-actor.c:
|
||||
(_get_actor_extents): use gfloat instead of gint, as now this clutter_actor_get_anchor_point
|
||||
use floats
|
||||
|
||||
2009-06-11 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Minor fixes
|
||||
|
||||
* Update TODO
|
||||
* Fix .pc files, to use clutter-0.9 version
|
||||
|
||||
2009-05-20 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Library renamed from cail to cally
|
||||
|
||||
|
||||
2009-05-08 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Removed cail-clone-texture.h from cail.h
|
||||
|
||||
* cail/cail.h: Removed reference to cail-clone-texture.h
|
||||
|
||||
2009-05-08 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Upgrade to cail-0.9, using clutter-0.9, first compilable version
|
||||
|
||||
* NEWS: new file with the information of the releases
|
||||
* TODO: updated
|
||||
* configure.ac: updated clutter version to compile against
|
||||
* cail/cail-clone-texture.[ch]: Removed as ClutterCloneTexture was removed on Clutter 0.9.0
|
||||
* cail/cail-label.[ch]: Removed as ClutterLabel was removed on Clutter 0.9.0
|
||||
* cail/Makefile.am: updated due the source files removed
|
||||
* cail/cail-actor.c: removed include to <clutter/clutter-actor.h>
|
||||
* cail/cail.c: removed the factories for CailLabel and CailCloneTexture
|
||||
|
||||
2009-05-07 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Reflect change on the version number policy
|
||||
|
||||
* README: correct some typos and explain that the cail version number
|
||||
is tied to the clutter version number and how
|
||||
* configure.ac
|
||||
Set the version number to 0.8.0
|
||||
|
||||
2009-05-07 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Edit the ChangeLog file, to show that now we are using git
|
||||
|
||||
* ChangeLog.SVN: new file, with the ChangeLog used while cail was
|
||||
using a Subversion repository
|
||||
* ChangeLog: now is empty, and only maintains a reference to use git log
|
||||
|
||||
2009-04-29 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Coding style review
|
||||
|
||||
* CODING_STYLE
|
||||
* cail/Makefile.am
|
||||
* cail/cail-actor-private.[ch]
|
||||
* cail/cail-actor.h
|
||||
* cail/cail-clone-texture.[ch]
|
||||
* cail/cail-group.[ch]
|
||||
* cail/cail-label.[ch]
|
||||
* cail/cail-rectangle.[ch]
|
||||
* cail/cail-root.[ch]
|
||||
* cail/cail-stage.[ch]
|
||||
* cail/cail-texture.[ch]
|
||||
* cail/cail-util.[ch]
|
||||
* cail/cail.c
|
||||
|
||||
2009-04-28 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Coding style review: cail-actor.c
|
||||
|
||||
|
||||
2009-04-21 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-04-21 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* TODO: updated TODO file
|
||||
|
||||
2009-04-21 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-03-06 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* AUTHORS: update authors file to public release
|
||||
|
||||
2009-03-06 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-03-06 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* debian/control
|
||||
Added cdbs dependency, renamed debugging package
|
||||
* debian/libcail-common-dbg.dirs: new file
|
||||
* debian/libcail-common.dirs
|
||||
* debian/libcail-common.install
|
||||
Minor changes
|
||||
|
||||
2009-03-05 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-03-05 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* TODO
|
||||
Added TODO file, in order to list the remaining tasks.
|
||||
|
||||
2009-03-05 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-03-05 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* configure.ac
|
||||
* cail/cail.c
|
||||
* cail/cail-util.c
|
||||
* Makefile.am
|
||||
Removed all the missing gtk related stuff
|
||||
|
||||
2009-03-05 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-03-05 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* cail/cail-actor.c
|
||||
(_get_actor_extents): managing too the anchor point to compute the position
|
||||
(_get_top_level_origin): reimplemented using x11 functions, removed
|
||||
gtk/gdk related functions, and taking into account the relative position
|
||||
inside the parent (previous position calculation was wrong if a child
|
||||
was not a direct stage child)
|
||||
* cail/clutter-gtk/cail-clutter-embed.[ch]
|
||||
* cail/clutter-gtk/cail-gtk-factory.h
|
||||
Removed, in order to remove any gtk dependency
|
||||
* cail/debian/control: removed gtk dependency
|
||||
|
||||
2009-03-03 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-03-03 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* cail/cail-actor-private.[ch]: new files to private utility functions
|
||||
(_cail_actor_pushable): new function, that checks if a cail actor is
|
||||
pushable by checking if the clutter actor related has a handler for
|
||||
a release event
|
||||
* cail/cail-texture.c
|
||||
* cail/cail-clone-texture.c
|
||||
* cail/cail-rectangle.c
|
||||
Use of new function _cail_actor_pushable
|
||||
* cail-actor.c: Added some documentation related to current implementation
|
||||
* cail-util.c: Code style review
|
||||
|
||||
2009-03-02 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-03-02 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* cail/cail-label.[ch]: new
|
||||
* cail/cail.[ch]
|
||||
(cail_accessibility_module_init)
|
||||
* cail/Makefile.am
|
||||
Added CailLabel, a11y object for ClutterLabel
|
||||
|
||||
2009-02-27 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-02-27 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* cail/cail-actor.c
|
||||
(cail_actor_real_remove_actor)
|
||||
Fixed a typo that causes a crash while removing the actor from a
|
||||
container
|
||||
|
||||
2009-02-26 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-02-26 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* cail/cail-actor.c
|
||||
(cail_actor_remove_actor)
|
||||
(cail_actor_add_actor)
|
||||
Fixed a typo calling klass->add_actor and klass->remove_actor that causes
|
||||
a crash in some (container,actor) combinations
|
||||
|
||||
(cail_actor_real_add_actor)
|
||||
Additional parameter check
|
||||
|
||||
2009-02-25 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
Missing cail-rectangle.[ch] files, according 2009-02-23 entry at Changelog
|
||||
|
||||
|
||||
2009-02-23 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-02-23 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* cail/cail-rectangle.[ch]
|
||||
* cail/cail.[ch]
|
||||
* cail/Makefile.am
|
||||
|
||||
Added CailRectangle, a11y object for ClutterRectangle
|
||||
|
||||
* cail/cail-group.c
|
||||
* cail/cail-texture.c
|
||||
* cail/cail-stage.c
|
||||
|
||||
Avoid to add a empty private structure, to avoid the glib warning. Anyway
|
||||
the pointer to the private structure is still on the .h, to allow future
|
||||
add-on.
|
||||
|
||||
2009-02-20 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-02-20 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* cail-actor.[ch]
|
||||
* cail-group.[ch]
|
||||
|
||||
Moved most of the ClutterContainer a11y support from cail-group to
|
||||
cail-actor, in order to generalize this support.
|
||||
|
||||
* cail-stage.[ch]
|
||||
* cail-util.[ch]
|
||||
Normalize the private structure to avoid future problems with missing
|
||||
gaps
|
||||
|
||||
2009-02-20 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-02-20 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* cail/cail-actor.c
|
||||
(cail_actor_connect_actor_destroyed): connects to the clutter actor
|
||||
destroy signal
|
||||
(cail_actor_clutter_actor_destroyed): handler to the clutter actor
|
||||
destroy signal, update the priv->actor pointer and notify a state change
|
||||
|
||||
This change allows to be sure about the priv->actor correct value, so we
|
||||
can use directly priv->actor instead of atk_gobject_accessible_get_object
|
||||
in the next functions:
|
||||
(cail_actor_get_parent)
|
||||
(cail_actor_get_index_in_parent)
|
||||
(cail_actor_ref_state_set)
|
||||
(cail_actor_get_extents)
|
||||
|
||||
2009-02-19 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-02-19 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* cail/cail-texture.[ch]
|
||||
* cail/cail-clone-texture.[ch]
|
||||
* cail/cail.[ch]
|
||||
* cail/Makefile.am
|
||||
|
||||
Added CailTexture and CailCloneTexture a11y objects for ClutterTexture
|
||||
and ClutterCloneTexture
|
||||
|
||||
* cail/cail-util.c
|
||||
|
||||
Added private structure
|
||||
|
||||
2009-02-18 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-02-18 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* cail/cail-actor.c:
|
||||
(cail_actor_get_parent)
|
||||
Return the accessible object of the clutter actor if accessible_parent
|
||||
is not available. Previously it only took into account the these object
|
||||
as a possible parent to return (you can set it with atk_object_set_parent)
|
||||
|
||||
2009-02-18 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-02-18 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* cail/cail-group.[ch]: code style review
|
||||
* cail/cail-actor.[ch]: implemented basic support for ClutterContainer
|
||||
|
||||
2009-02-18 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-02-18 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* debian/control: updating dependencies
|
||||
|
||||
2009-02-18 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-02-18 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* configure.ac: added aditional compile flags
|
||||
* cail/cail-actor.[ch]: Reimplemented support for AtkAction interface
|
||||
* cail/cail-root.[ch]: code style review
|
||||
|
||||
2009-02-16 Alejandro Piñeiro <apinheiro@igalia.com>
|
||||
|
||||
2009-02-16 Alejandro Pinheiro <apinheiro@igalia.com>
|
||||
|
||||
* First release.
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Clutter.
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
@@ -22,35 +22,21 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CALLY_ACTOR_PRIVATE_H__
|
||||
#define __CALLY_ACTOR_PRIVATE_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
#include "cally-actor.h"
|
||||
|
||||
#include <atk/atk.h>
|
||||
/*
|
||||
* Auxiliar define, in order to get the clutter actor from the AtkObject using
|
||||
* AtkGObject methods
|
||||
*
|
||||
*/
|
||||
#define CALLY_GET_CLUTTER_ACTOR(cally_object) \
|
||||
(CLUTTER_ACTOR (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (cally_object))))
|
||||
|
||||
#include "clutter/clutter-macros.h"
|
||||
void _cally_actor_get_top_level_origin (ClutterActor *actor,
|
||||
gint *x,
|
||||
gint *y);
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_ACTOR_ACCESSIBLE (clutter_actor_accessible_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterActorAccessible,
|
||||
clutter_actor_accessible,
|
||||
CLUTTER,
|
||||
ACTOR_ACCESSIBLE,
|
||||
AtkGObjectAccessible)
|
||||
|
||||
typedef struct _ClutterActorAccessible ClutterActorAccessible;
|
||||
typedef struct _ClutterActorAccessibleClass ClutterActorAccessibleClass;
|
||||
typedef struct _ClutterActorAccessiblePrivate ClutterActorAccessiblePrivate;
|
||||
|
||||
struct _ClutterActorAccessibleClass
|
||||
{
|
||||
/*< private >*/
|
||||
AtkGObjectAccessibleClass parent_class;
|
||||
};
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __CALLY_ACTOR_PRIVATE_H__ */
|
||||
1243
clutter/clutter/cally/cally-actor.c
Normal file
1243
clutter/clutter/cally/cally-actor.c
Normal file
File diff suppressed because it is too large
Load Diff
160
clutter/clutter/cally/cally-actor.h
Normal file
160
clutter/clutter/cally/cally-actor.h
Normal file
@@ -0,0 +1,160 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* Some parts are based on GailWidget from GAIL
|
||||
* GAIL - The GNOME Accessibility Implementation Library
|
||||
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CALLY_ACTOR_H__
|
||||
#define __CALLY_ACTOR_H__
|
||||
|
||||
#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <cally/cally.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <atk/atk.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CALLY_TYPE_ACTOR (cally_actor_get_type ())
|
||||
#define CALLY_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_ACTOR, CallyActor))
|
||||
#define CALLY_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_ACTOR, CallyActorClass))
|
||||
#define CALLY_IS_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_ACTOR))
|
||||
#define CALLY_IS_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_ACTOR))
|
||||
#define CALLY_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_ACTOR, CallyActorClass))
|
||||
|
||||
typedef struct _CallyActor CallyActor;
|
||||
typedef struct _CallyActorClass CallyActorClass;
|
||||
typedef struct _CallyActorPrivate CallyActorPrivate;
|
||||
|
||||
/**
|
||||
* CallyActionFunc:
|
||||
* @cally_actor: a #CallyActor
|
||||
*
|
||||
* Action function, to be used on #AtkAction implementations as a individual
|
||||
* action
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
typedef void (* CallyActionFunc) (CallyActor *cally_actor);
|
||||
|
||||
/**
|
||||
* CallyActionCallback:
|
||||
* @cally_actor: a #CallyActor
|
||||
* @user_data: user data passed to the function
|
||||
*
|
||||
* Action function, to be used on #AtkAction implementations as
|
||||
* an individual action. Unlike #CallyActionFunc, this function
|
||||
* uses the @user_data argument passed to cally_actor_add_action_full().
|
||||
*
|
||||
* Since: 1.6
|
||||
*/
|
||||
typedef void (* CallyActionCallback) (CallyActor *cally_actor,
|
||||
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
|
||||
{
|
||||
/*< private >*/
|
||||
AtkGObjectAccessible parent;
|
||||
|
||||
CallyActorPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* CallyActorClass:
|
||||
* @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
|
||||
* ClutterContainer interface
|
||||
* @remove_actor: Signal handler for actor-added signal on
|
||||
* ClutterContainer interface
|
||||
*
|
||||
* The <structname>CallyActorClass</structname> structure contains
|
||||
* only private data
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _CallyActorClass
|
||||
{
|
||||
/*< private >*/
|
||||
AtkGObjectAccessibleClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
void (*notify_clutter) (GObject *object,
|
||||
GParamSpec *pspec);
|
||||
|
||||
gboolean (*focus_clutter) (ClutterActor *actor,
|
||||
gpointer data);
|
||||
|
||||
gint (*add_actor) (ClutterActor *container,
|
||||
ClutterActor *actor,
|
||||
gpointer data);
|
||||
|
||||
gint (*remove_actor) (ClutterActor *container,
|
||||
ClutterActor *actor,
|
||||
gpointer data);
|
||||
|
||||
/*< private >*/
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[32];
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType cally_actor_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
AtkObject* cally_actor_new (ClutterActor *actor);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
guint cally_actor_add_action (CallyActor *cally_actor,
|
||||
const gchar *action_name,
|
||||
const gchar *action_description,
|
||||
const gchar *action_keybinding,
|
||||
CallyActionFunc action_func);
|
||||
CLUTTER_EXPORT
|
||||
guint cally_actor_add_action_full (CallyActor *cally_actor,
|
||||
const gchar *action_name,
|
||||
const gchar *action_description,
|
||||
const gchar *action_keybinding,
|
||||
CallyActionCallback callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify notify);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean cally_actor_remove_action (CallyActor *cally_actor,
|
||||
gint action_id);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean cally_actor_remove_action_by_name (CallyActor *cally_actor,
|
||||
const gchar *action_name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CALLY_ACTOR_H__ */
|
||||
132
clutter/clutter/cally/cally-clone.c
Normal file
132
clutter/clutter/cally/cally-clone.c
Normal file
@@ -0,0 +1,132 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2010 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:cally-clone
|
||||
* @Title: CallyClone
|
||||
* @short_description: Implementation of the ATK interfaces for a #ClutterClone
|
||||
* @see_also: #ClutterClone
|
||||
*
|
||||
* #CallyClone implements the required ATK interfaces of #ClutterClone
|
||||
*
|
||||
* In particular it sets a proper role for the clone, as just a image,
|
||||
* as it is the sanest and simplest approach.
|
||||
*/
|
||||
|
||||
/* Design rationale for CallyClone:
|
||||
*
|
||||
* In the old times, it was just ClutterCloneTexture. So, from a a11y POV
|
||||
* CallyCloneTexture was just another image, like ClutterTexture, and if
|
||||
* it was a clone was irrevelant. So on cally-0.8, CallyCloneTexture
|
||||
* expose a object with role ATK_ROLE_IMAGE. But now, ClutterClone is more
|
||||
* general. You can clone any object, including groups, and made things
|
||||
* like have one text entry, and a clone with different properties in the
|
||||
* same window, updated both at once.
|
||||
*
|
||||
* The question is if the idea is have a ClutterClone as a "first-class"
|
||||
* citizen inside the stage hierarchy (full clone), or it is just supposed
|
||||
* to be a mirror image of the original object.
|
||||
*
|
||||
* In the case of the a11y POV this would mean that if the text changes on
|
||||
* the source, the clone should emit as well the text-changing signals.
|
||||
*
|
||||
* As ClutterClone smartly just paint the same object with different
|
||||
* parameters, this would mean that it should be the cally object the one
|
||||
* that should replicate the source clutter hierarchy to do that,
|
||||
* something that just sound crazy.
|
||||
*
|
||||
* Taking into account that:
|
||||
*
|
||||
* - ClutterClone doesn't re-emit mirrored signals from the source
|
||||
* I think that likely the answer would be "yes, it is just a
|
||||
* mirrored image, not a real full clone".
|
||||
*
|
||||
* - You can't interact directly with the clone (ie: focus, and so on).
|
||||
* Its basic usage (right now) is clone textures.
|
||||
*
|
||||
* Any other solution could be overwhelming.
|
||||
*
|
||||
* I think that the final solution would be that ClutterClone from the
|
||||
* a11y POV should still be managed as a image (with the proper properties,
|
||||
* position, size, etc.).
|
||||
*/
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "cally-clone.h"
|
||||
#include "cally-actor-private.h"
|
||||
|
||||
/* AtkObject */
|
||||
static void cally_clone_real_initialize (AtkObject *obj,
|
||||
gpointer data);
|
||||
|
||||
G_DEFINE_TYPE (CallyClone, cally_clone, CALLY_TYPE_ACTOR)
|
||||
|
||||
static void
|
||||
cally_clone_class_init (CallyCloneClass *klass)
|
||||
{
|
||||
/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */
|
||||
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
|
||||
|
||||
class->initialize = cally_clone_real_initialize;
|
||||
}
|
||||
|
||||
static void
|
||||
cally_clone_init (CallyClone *clone)
|
||||
{
|
||||
/* nothing to do yet */
|
||||
}
|
||||
|
||||
/**
|
||||
* cally_clone_new:
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* Creates a new #CallyClone for the given @actor. @actor must be a
|
||||
* #ClutterClone.
|
||||
*
|
||||
* Return value: the newly created #AtkObject
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
AtkObject*
|
||||
cally_clone_new (ClutterActor *actor)
|
||||
{
|
||||
GObject *object = NULL;
|
||||
AtkObject *accessible = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_CLONE (actor), NULL);
|
||||
|
||||
object = g_object_new (CALLY_TYPE_CLONE, NULL);
|
||||
|
||||
accessible = ATK_OBJECT (object);
|
||||
atk_object_initialize (accessible, actor);
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
static void
|
||||
cally_clone_real_initialize (AtkObject *obj,
|
||||
gpointer data)
|
||||
{
|
||||
ATK_OBJECT_CLASS (cally_clone_parent_class)->initialize (obj, data);
|
||||
|
||||
obj->role = ATK_ROLE_IMAGE;
|
||||
}
|
||||
84
clutter/clutter/cally/cally-clone.h
Normal file
84
clutter/clutter/cally/cally-clone.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2010 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CALLY_CLONE_H__
|
||||
#define __CALLY_CLONE_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_CLONE (cally_clone_get_type ())
|
||||
#define CALLY_CLONE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_CLONE, CallyClone))
|
||||
#define CALLY_CLONE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_CLONE, CallyCloneClass))
|
||||
#define CALLY_IS_CLONE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_CLONE))
|
||||
#define CALLY_IS_CLONE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_CLONE))
|
||||
#define CALLY_CLONE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_CLONE, CallyCloneClass))
|
||||
|
||||
typedef struct _CallyClone CallyClone;
|
||||
typedef struct _CallyCloneClass CallyCloneClass;
|
||||
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
|
||||
{
|
||||
/*< private >*/
|
||||
CallyActor parent;
|
||||
|
||||
CallyClonePrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* CallyCloneClass:
|
||||
*
|
||||
* The <structname>CallyCloneClass</structname> structure contains only
|
||||
* private data
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _CallyCloneClass
|
||||
{
|
||||
/*< private >*/
|
||||
CallyActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[8];
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType cally_clone_get_type (void) G_GNUC_CONST;
|
||||
CLUTTER_EXPORT
|
||||
AtkObject *cally_clone_new (ClutterActor *actor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CALLY_CLONE_H__ */
|
||||
117
clutter/clutter/cally/cally-factory.h
Normal file
117
clutter/clutter/cally/cally-factory.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* Based on gailfactory.h from GAIL
|
||||
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _CALLY_FACTORY_H__
|
||||
#define _CALLY_FACTORY_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <atk/atkobject.h>
|
||||
|
||||
/**
|
||||
* CALLY_ACCESSIBLE_FACTORY:
|
||||
* @type: GType of the accessible which is created by the factory
|
||||
* @type_as_function: prefix of the accessible object methods
|
||||
* @opt_create_accessible: method to instantiate the accessibility object
|
||||
*
|
||||
* Defines a new #AtkObjectFactory factory to create accessible
|
||||
* objects of a specific GType. It defines the factory GType and also
|
||||
* overrides the proper #AtkObjectFactory methods.
|
||||
*
|
||||
* It assumes that the accessibility object provides a
|
||||
* @opt_create_accessible method in order to create the accessibility
|
||||
* object. It returns a @type GType object.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
#define CALLY_ACCESSIBLE_FACTORY(type, type_as_function, opt_create_accessible) \
|
||||
\
|
||||
static GType \
|
||||
type_as_function ## _factory_get_accessible_type (void) \
|
||||
{ \
|
||||
return type; \
|
||||
} \
|
||||
\
|
||||
static AtkObject* \
|
||||
type_as_function ## _factory_create_accessible (GObject *obj) \
|
||||
{ \
|
||||
ClutterActor *actor; \
|
||||
AtkObject *accessible; \
|
||||
\
|
||||
g_return_val_if_fail (CLUTTER_ACTOR (obj), NULL); \
|
||||
\
|
||||
actor = CLUTTER_ACTOR (obj); \
|
||||
\
|
||||
accessible = opt_create_accessible (actor); \
|
||||
\
|
||||
return accessible; \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
type_as_function ## _factory_class_init (AtkObjectFactoryClass *klass) \
|
||||
{ \
|
||||
klass->create_accessible = type_as_function ## _factory_create_accessible; \
|
||||
klass->get_accessible_type = type_as_function ## _factory_get_accessible_type;\
|
||||
} \
|
||||
\
|
||||
static GType \
|
||||
type_as_function ## _factory_get_type (void) \
|
||||
{ \
|
||||
static GType t = 0; \
|
||||
\
|
||||
if (!t) \
|
||||
{ \
|
||||
char *name; \
|
||||
static const GTypeInfo tinfo = \
|
||||
{ \
|
||||
sizeof (AtkObjectFactoryClass), \
|
||||
NULL, NULL, (GClassInitFunc) type_as_function ## _factory_class_init, \
|
||||
NULL, NULL, sizeof (AtkObjectFactory), 0, NULL, NULL \
|
||||
}; \
|
||||
\
|
||||
name = g_strconcat (g_type_name (type), "Factory", NULL); \
|
||||
t = g_type_register_static ( \
|
||||
ATK_TYPE_OBJECT_FACTORY, name, &tinfo, 0); \
|
||||
g_free (name); \
|
||||
} \
|
||||
\
|
||||
return t; \
|
||||
}
|
||||
|
||||
/**
|
||||
* CALLY_ACTOR_SET_FACTORY:
|
||||
* @widget_type: GType of the clutter actor
|
||||
* @type_as_function: prefix of the accessible object methods
|
||||
*
|
||||
* Sets the #AtkObjectFactory to be used in order to instantiate
|
||||
* accessibility objects for the actor which GType is @widget_type.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
#define CALLY_ACTOR_SET_FACTORY(widget_type, type_as_function) \
|
||||
atk_registry_set_factory_type (atk_get_default_registry (), \
|
||||
widget_type, \
|
||||
type_as_function ## _factory_get_type ())
|
||||
|
||||
#endif /* _CALLY_FACTORY_H__ */
|
||||
147
clutter/clutter/cally/cally-group.c
Normal file
147
clutter/clutter/cally/cally-group.c
Normal file
@@ -0,0 +1,147 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* Based on GailContainer from GAIL
|
||||
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:cally-group
|
||||
* @Title: CallyGroup
|
||||
* @short_description: Implementation of the ATK interfaces for a #ClutterGroup
|
||||
* @see_also: #ClutterGroup
|
||||
*
|
||||
* #CallyGroup implements the required ATK interfaces of #ClutterGroup
|
||||
* In particular it exposes each of the Clutter actors contained in the
|
||||
* group.
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "cally-group.h"
|
||||
#include "cally-actor-private.h"
|
||||
|
||||
static gint cally_group_get_n_children (AtkObject *obj);
|
||||
static AtkObject* cally_group_ref_child (AtkObject *obj,
|
||||
gint i);
|
||||
static void cally_group_real_initialize (AtkObject *obj,
|
||||
gpointer data);
|
||||
|
||||
G_DEFINE_TYPE (CallyGroup, cally_group, CALLY_TYPE_ACTOR)
|
||||
|
||||
static void
|
||||
cally_group_class_init (CallyGroupClass *klass)
|
||||
{
|
||||
/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */
|
||||
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
|
||||
|
||||
class->get_n_children = cally_group_get_n_children;
|
||||
class->ref_child = cally_group_ref_child;
|
||||
class->initialize = cally_group_real_initialize;
|
||||
}
|
||||
|
||||
static void
|
||||
cally_group_init (CallyGroup *group)
|
||||
{
|
||||
/* nothing to do yet */
|
||||
}
|
||||
|
||||
/**
|
||||
* cally_group_new:
|
||||
* @actor: a #ClutterGroup
|
||||
*
|
||||
* Creates a #CallyGroup for @actor
|
||||
*
|
||||
* Return value: the newly created #CallyGroup
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
AtkObject *
|
||||
cally_group_new (ClutterActor *actor)
|
||||
{
|
||||
GObject *object = NULL;
|
||||
AtkObject *accessible = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_GROUP (actor), NULL);
|
||||
|
||||
object = g_object_new (CALLY_TYPE_GROUP, NULL);
|
||||
|
||||
accessible = ATK_OBJECT (object);
|
||||
atk_object_initialize (accessible, actor);
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
static gint
|
||||
cally_group_get_n_children (AtkObject *obj)
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
gint count = 0;
|
||||
|
||||
g_return_val_if_fail (CALLY_IS_GROUP (obj), count);
|
||||
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (obj);
|
||||
|
||||
if (actor == NULL) /* defunct */
|
||||
return 0;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_GROUP(actor), count);
|
||||
|
||||
count = clutter_actor_get_n_children (actor);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static AtkObject*
|
||||
cally_group_ref_child (AtkObject *obj,
|
||||
gint i)
|
||||
{
|
||||
AtkObject *accessible = NULL;
|
||||
ClutterActor *actor = NULL;
|
||||
ClutterActor *child = NULL;
|
||||
|
||||
g_return_val_if_fail (CALLY_IS_GROUP (obj), NULL);
|
||||
g_return_val_if_fail ((i >= 0), NULL);
|
||||
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (obj);
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_GROUP(actor), NULL);
|
||||
child = clutter_actor_get_child_at_index (actor, i);
|
||||
|
||||
if (!child)
|
||||
return NULL;
|
||||
|
||||
accessible = clutter_actor_get_accessible (child);
|
||||
|
||||
if (accessible != NULL)
|
||||
g_object_ref (accessible);
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
static void
|
||||
cally_group_real_initialize (AtkObject *obj,
|
||||
gpointer data)
|
||||
{
|
||||
ATK_OBJECT_CLASS (cally_group_parent_class)->initialize (obj, data);
|
||||
|
||||
obj->role = ATK_ROLE_PANEL;
|
||||
}
|
||||
87
clutter/clutter/cally/cally-group.h
Normal file
87
clutter/clutter/cally/cally-group.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* Based on GailContainer from GAIL
|
||||
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CALLY_GROUP_H__
|
||||
#define __CALLY_GROUP_H__
|
||||
|
||||
#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <cally/cally.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <cally/cally-actor.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CALLY_TYPE_GROUP (cally_group_get_type ())
|
||||
#define CALLY_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_GROUP, CallyGroup))
|
||||
#define CALLY_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_GROUP, CallyGroupClass))
|
||||
#define CALLY_IS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_GROUP))
|
||||
#define CALLY_IS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_GROUP))
|
||||
#define CALLY_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_GROUP, CallyGroupClass))
|
||||
|
||||
typedef struct _CallyGroup CallyGroup;
|
||||
typedef struct _CallyGroupClass CallyGroupClass;
|
||||
typedef struct _CallyGroupPrivate CallyGroupPrivate;
|
||||
|
||||
/**
|
||||
* CallyGroup:
|
||||
*
|
||||
* The <structname>CallyGroup</structname> structure contains only
|
||||
* private data and should be accessed using the provided API
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _CallyGroup
|
||||
{
|
||||
/*< private >*/
|
||||
CallyActor parent;
|
||||
|
||||
CallyGroupPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* CallyGroupClass:
|
||||
*
|
||||
* The <structname>CallyGroupClass</structname> structure contains only
|
||||
* private data
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _CallyGroupClass
|
||||
{
|
||||
/*< private >*/
|
||||
CallyActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[8];
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType cally_group_get_type (void) G_GNUC_CONST;
|
||||
CLUTTER_EXPORT
|
||||
AtkObject* cally_group_new (ClutterActor *actor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CALLY_GROUP_H__ */
|
||||
@@ -1,9 +1,13 @@
|
||||
/* Clutter.
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* Some parts are based on GailWidget from GAIL
|
||||
* GAIL - The GNOME Accessibility Implementation Library
|
||||
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
@@ -18,19 +22,23 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CALLY_MAIN_H__
|
||||
#define __CALLY_MAIN_H__
|
||||
|
||||
#include "clutter/clutter-actor-accessible.h"
|
||||
#include "clutter/clutter-macros.h"
|
||||
#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <cally/cally.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <atk/atk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_STAGE_ACCESSIBLE (clutter_stage_accessible_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ClutterStageAccessible,
|
||||
clutter_stage_accessible,
|
||||
CLUTTER,
|
||||
STAGE_ACCESSIBLE,
|
||||
ClutterActorAccessible)
|
||||
CLUTTER_EXPORT
|
||||
gboolean cally_get_cally_initialized (void);
|
||||
CLUTTER_EXPORT
|
||||
gboolean cally_accessibility_init (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CALLY_MAIN_H__ */
|
||||
98
clutter/clutter/cally/cally-rectangle.c
Normal file
98
clutter/clutter/cally/cally-rectangle.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2009 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:cally-rectangle
|
||||
* @short_description: Implementation of the ATK interfaces for a #ClutterRectangle
|
||||
* @see_also: #ClutterRectangle
|
||||
*
|
||||
* #CallyRectangle implements the required ATK interfaces of #ClutterRectangle
|
||||
*
|
||||
* In particular it sets a proper role for the rectangle.
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#include "cally-rectangle.h"
|
||||
#include "cally-actor-private.h"
|
||||
|
||||
#include "clutter-color.h"
|
||||
#include "deprecated/clutter-rectangle.h"
|
||||
|
||||
/* AtkObject */
|
||||
static void cally_rectangle_real_initialize (AtkObject *obj,
|
||||
gpointer data);
|
||||
|
||||
G_DEFINE_TYPE (CallyRectangle, cally_rectangle, CALLY_TYPE_ACTOR)
|
||||
|
||||
static void
|
||||
cally_rectangle_class_init (CallyRectangleClass *klass)
|
||||
{
|
||||
/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */
|
||||
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
|
||||
|
||||
class->initialize = cally_rectangle_real_initialize;
|
||||
}
|
||||
|
||||
static void
|
||||
cally_rectangle_init (CallyRectangle *rectangle)
|
||||
{
|
||||
/* nothing to do yet */
|
||||
}
|
||||
|
||||
/**
|
||||
* cally_rectangle_new:
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* Creates a new #CallyRectangle for the given @actor. @actor must be
|
||||
* a #ClutterRectangle.
|
||||
*
|
||||
* Return value: the newly created #AtkObject
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
AtkObject*
|
||||
cally_rectangle_new (ClutterActor *actor)
|
||||
{
|
||||
GObject *object = NULL;
|
||||
AtkObject *accessible = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_RECTANGLE (actor), NULL);
|
||||
|
||||
object = g_object_new (CALLY_TYPE_RECTANGLE, NULL);
|
||||
|
||||
accessible = ATK_OBJECT (object);
|
||||
atk_object_initialize (accessible, actor);
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
static void
|
||||
cally_rectangle_real_initialize (AtkObject *obj,
|
||||
gpointer data)
|
||||
{
|
||||
ATK_OBJECT_CLASS (cally_rectangle_parent_class)->initialize (obj, data);
|
||||
|
||||
obj->role = ATK_ROLE_IMAGE;
|
||||
}
|
||||
84
clutter/clutter/cally/cally-rectangle.h
Normal file
84
clutter/clutter/cally/cally-rectangle.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2009 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CALLY_RECTANGLE_H__
|
||||
#define __CALLY_RECTANGLE_H__
|
||||
|
||||
#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <cally/cally.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <cally/cally-actor.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CALLY_TYPE_RECTANGLE (cally_rectangle_get_type ())
|
||||
#define CALLY_RECTANGLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_RECTANGLE, CallyRectangle))
|
||||
#define CALLY_RECTANGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_RECTANGLE, CallyRectangleClass))
|
||||
#define CALLY_IS_RECTANGLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_RECTANGLE))
|
||||
#define CALLY_IS_RECTANGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_RECTANGLE))
|
||||
#define CALLY_RECTANGLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_RECTANGLE, CallyRectangleClass))
|
||||
|
||||
typedef struct _CallyRectangle CallyRectangle;
|
||||
typedef struct _CallyRectangleClass CallyRectangleClass;
|
||||
typedef struct _CallyRectanglePrivate CallyRectanglePrivate;
|
||||
|
||||
/**
|
||||
* CallyRectangle:
|
||||
*
|
||||
* The <structname>CallyRectangle</structname> structure contains only private
|
||||
* data and should be accessed using the provided API
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _CallyRectangle
|
||||
{
|
||||
/*< private >*/
|
||||
CallyActor parent;
|
||||
|
||||
CallyRectanglePrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* CallyRectangleClass:
|
||||
*
|
||||
* The <structname>CallyRectangleClass</structname> structure contains
|
||||
* only private data
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _CallyRectangleClass
|
||||
{
|
||||
/*< private >*/
|
||||
CallyActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[8];
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType cally_rectangle_get_type (void) G_GNUC_CONST;
|
||||
CLUTTER_EXPORT
|
||||
AtkObject* cally_rectangle_new (ClutterActor *actor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CALLY_RECTANGLE_H__ */
|
||||
294
clutter/clutter/cally/cally-root.c
Normal file
294
clutter/clutter/cally/cally-root.c
Normal file
@@ -0,0 +1,294 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:cally-root
|
||||
* @short_description: Root object for the Cally toolkit
|
||||
* @see_also: #ClutterStage
|
||||
*
|
||||
* #CallyRoot is the root object of the accessibility tree-like
|
||||
* hierarchy, exposing the application level.
|
||||
*
|
||||
* Somewhat equivalent to #GailTopLevel. We consider that this class
|
||||
* expose the a11y information of the #ClutterStageManager, as the
|
||||
* children of this object are the different ClutterStage managed (so
|
||||
* the #GObject used in the atk_object_initialize() is the
|
||||
* #ClutterStageManager).
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "cally-root.h"
|
||||
|
||||
#include "clutter-actor.h"
|
||||
#include "clutter-stage-private.h"
|
||||
#include "clutter-stage-manager.h"
|
||||
|
||||
|
||||
/* GObject */
|
||||
static void cally_root_finalize (GObject *object);
|
||||
|
||||
/* AtkObject.h */
|
||||
static void cally_root_initialize (AtkObject *accessible,
|
||||
gpointer data);
|
||||
static gint cally_root_get_n_children (AtkObject *obj);
|
||||
static AtkObject * cally_root_ref_child (AtkObject *obj,
|
||||
gint i);
|
||||
static AtkObject * cally_root_get_parent (AtkObject *obj);
|
||||
static const char * cally_root_get_name (AtkObject *obj);
|
||||
|
||||
/* Private */
|
||||
static void cally_util_stage_added_cb (ClutterStageManager *stage_manager,
|
||||
ClutterStage *stage,
|
||||
gpointer data);
|
||||
static void cally_util_stage_removed_cb (ClutterStageManager *stage_manager,
|
||||
ClutterStage *stage,
|
||||
gpointer data);
|
||||
|
||||
struct _CallyRootPrivate
|
||||
{
|
||||
/* We save the CallyStage objects. Other option could save the stage
|
||||
* list, and then just get the a11y object on the ref_child, etc. But
|
||||
* the ref_child is more common that the init and the stage-add,
|
||||
* stage-remove, so we avoid getting the accessible object
|
||||
* constantly
|
||||
*/
|
||||
GSList *stage_list;
|
||||
|
||||
/* signals id */
|
||||
guint stage_added_id;
|
||||
guint stage_removed_id;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (CallyRoot, cally_root, ATK_TYPE_GOBJECT_ACCESSIBLE)
|
||||
|
||||
static void
|
||||
cally_root_class_init (CallyRootClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = cally_root_finalize;
|
||||
|
||||
/* AtkObject */
|
||||
class->get_n_children = cally_root_get_n_children;
|
||||
class->ref_child = cally_root_ref_child;
|
||||
class->get_parent = cally_root_get_parent;
|
||||
class->initialize = cally_root_initialize;
|
||||
class->get_name = cally_root_get_name;
|
||||
}
|
||||
|
||||
static void
|
||||
cally_root_init (CallyRoot *root)
|
||||
{
|
||||
root->priv = cally_root_get_instance_private (root);
|
||||
|
||||
root->priv->stage_list = NULL;
|
||||
root->priv->stage_added_id = 0;
|
||||
root->priv->stage_removed_id = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cally_root_new:
|
||||
*
|
||||
* Creates a new #CallyRoot object.
|
||||
*
|
||||
* Return value: the newly created #AtkObject
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
AtkObject*
|
||||
cally_root_new (void)
|
||||
{
|
||||
GObject *object = NULL;
|
||||
AtkObject *accessible = NULL;
|
||||
ClutterStageManager *stage_manager = NULL;
|
||||
|
||||
object = g_object_new (CALLY_TYPE_ROOT, NULL);
|
||||
|
||||
accessible = ATK_OBJECT (object);
|
||||
stage_manager = clutter_stage_manager_get_default ();
|
||||
|
||||
atk_object_initialize (accessible, stage_manager);
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
static void
|
||||
cally_root_finalize (GObject *object)
|
||||
{
|
||||
CallyRoot *root = CALLY_ROOT (object);
|
||||
GObject *stage_manager = NULL;
|
||||
|
||||
g_return_if_fail (CALLY_IS_ROOT (object));
|
||||
|
||||
if (root->priv->stage_list)
|
||||
{
|
||||
g_slist_free (root->priv->stage_list);
|
||||
root->priv->stage_list = NULL;
|
||||
}
|
||||
|
||||
stage_manager = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (root));
|
||||
|
||||
g_signal_handler_disconnect (stage_manager,
|
||||
root->priv->stage_added_id);
|
||||
|
||||
g_signal_handler_disconnect (stage_manager,
|
||||
root->priv->stage_added_id);
|
||||
|
||||
G_OBJECT_CLASS (cally_root_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/* AtkObject.h */
|
||||
static void
|
||||
cally_root_initialize (AtkObject *accessible,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterStageManager *stage_manager = NULL;
|
||||
const GSList *iter = NULL;
|
||||
const GSList *stage_list = NULL;
|
||||
ClutterStage *clutter_stage = NULL;
|
||||
AtkObject *cally_stage = NULL;
|
||||
CallyRoot *root = NULL;
|
||||
|
||||
accessible->role = ATK_ROLE_APPLICATION;
|
||||
accessible->accessible_parent = NULL;
|
||||
|
||||
/* children initialization */
|
||||
root = CALLY_ROOT (accessible);
|
||||
stage_manager = CLUTTER_STAGE_MANAGER (data);
|
||||
stage_list = clutter_stage_manager_peek_stages (stage_manager);
|
||||
|
||||
for (iter = stage_list; iter != NULL; iter = g_slist_next (iter))
|
||||
{
|
||||
clutter_stage = CLUTTER_STAGE (iter->data);
|
||||
cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (clutter_stage));
|
||||
|
||||
atk_object_set_parent (cally_stage, ATK_OBJECT (root));
|
||||
|
||||
root->priv->stage_list = g_slist_append (root->priv->stage_list,
|
||||
cally_stage);
|
||||
}
|
||||
|
||||
root->priv->stage_added_id =
|
||||
g_signal_connect (G_OBJECT (stage_manager), "stage-added",
|
||||
G_CALLBACK (cally_util_stage_added_cb), root);
|
||||
|
||||
root->priv->stage_removed_id =
|
||||
g_signal_connect (G_OBJECT (stage_manager), "stage-removed",
|
||||
G_CALLBACK (cally_util_stage_removed_cb), root);
|
||||
|
||||
ATK_OBJECT_CLASS (cally_root_parent_class)->initialize (accessible, data);
|
||||
}
|
||||
|
||||
|
||||
static gint
|
||||
cally_root_get_n_children (AtkObject *obj)
|
||||
{
|
||||
CallyRoot *root = CALLY_ROOT (obj);
|
||||
|
||||
return g_slist_length (root->priv->stage_list);
|
||||
}
|
||||
|
||||
static AtkObject*
|
||||
cally_root_ref_child (AtkObject *obj,
|
||||
gint i)
|
||||
{
|
||||
CallyRoot *cally_root = NULL;
|
||||
GSList *stage_list = NULL;
|
||||
gint num = 0;
|
||||
AtkObject *item = NULL;
|
||||
|
||||
cally_root = CALLY_ROOT (obj);
|
||||
stage_list = cally_root->priv->stage_list;
|
||||
num = g_slist_length (stage_list);
|
||||
|
||||
g_return_val_if_fail ((i < num)&&(i >= 0), NULL);
|
||||
|
||||
item = g_slist_nth_data (stage_list, i);
|
||||
if (!item)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_object_ref (item);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
static AtkObject*
|
||||
cally_root_get_parent (AtkObject *obj)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
cally_root_get_name (AtkObject *obj)
|
||||
{
|
||||
return g_get_prgname ();
|
||||
}
|
||||
|
||||
/* -------------------------------- PRIVATE --------------------------------- */
|
||||
|
||||
static void
|
||||
cally_util_stage_added_cb (ClutterStageManager *stage_manager,
|
||||
ClutterStage *stage,
|
||||
gpointer data)
|
||||
{
|
||||
CallyRoot *root = CALLY_ROOT (data);
|
||||
AtkObject *cally_stage = NULL;
|
||||
gint index = -1;
|
||||
|
||||
cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage));
|
||||
|
||||
atk_object_set_parent (cally_stage, ATK_OBJECT (root));
|
||||
|
||||
root->priv->stage_list = g_slist_append (root->priv->stage_list,
|
||||
cally_stage);
|
||||
|
||||
index = g_slist_index (root->priv->stage_list, cally_stage);
|
||||
g_signal_emit_by_name (root, "children_changed::add",
|
||||
index, cally_stage, NULL);
|
||||
g_signal_emit_by_name (cally_stage, "create", 0);
|
||||
}
|
||||
|
||||
static void
|
||||
cally_util_stage_removed_cb (ClutterStageManager *stage_manager,
|
||||
ClutterStage *stage,
|
||||
gpointer data)
|
||||
{
|
||||
CallyRoot *root = CALLY_ROOT (data);
|
||||
AtkObject *cally_stage = NULL;
|
||||
gint index = -1;
|
||||
|
||||
cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage));
|
||||
|
||||
index = g_slist_index (root->priv->stage_list, cally_stage);
|
||||
|
||||
root->priv->stage_list = g_slist_remove (root->priv->stage_list,
|
||||
cally_stage);
|
||||
|
||||
index = g_slist_index (root->priv->stage_list, cally_stage);
|
||||
g_signal_emit_by_name (root, "children_changed::remove",
|
||||
index, cally_stage, NULL);
|
||||
g_signal_emit_by_name (cally_stage, "destroy", 0);
|
||||
}
|
||||
84
clutter/clutter/cally/cally-root.h
Normal file
84
clutter/clutter/cally/cally-root.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2009 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CALLY_ROOT_H__
|
||||
#define __CALLY_ROOT_H__
|
||||
|
||||
#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <cally/cally.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <atk/atk.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CALLY_TYPE_ROOT (cally_root_get_type ())
|
||||
#define CALLY_ROOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_ROOT, CallyRoot))
|
||||
#define CALLY_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_ROOT, CallyRootClass))
|
||||
#define CALLY_IS_ROOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_ROOT))
|
||||
#define CALLY_IS_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_ROOT))
|
||||
#define CALLY_ROOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_ROOT, CallyRootClass))
|
||||
|
||||
typedef struct _CallyRoot CallyRoot;
|
||||
typedef struct _CallyRootClass CallyRootClass;
|
||||
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
|
||||
{
|
||||
/*< private >*/
|
||||
AtkGObjectAccessible parent;
|
||||
|
||||
CallyRootPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* CallyRootClass:
|
||||
*
|
||||
* The <structname>CallyRootClass</structname> structure contains only
|
||||
* private data
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _CallyRootClass
|
||||
{
|
||||
/*< private >*/
|
||||
AtkGObjectAccessibleClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[16];
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType cally_root_get_type (void) G_GNUC_CONST;
|
||||
CLUTTER_EXPORT
|
||||
AtkObject *cally_root_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CALLY_ROOT_H__ */
|
||||
260
clutter/clutter/cally/cally-stage.c
Normal file
260
clutter/clutter/cally/cally-stage.c
Normal file
@@ -0,0 +1,260 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:cally-stage
|
||||
* @Title: CallyStage
|
||||
* @short_description: Implementation of the ATK interfaces for a #ClutterStage
|
||||
* @see_also: #ClutterStage
|
||||
*
|
||||
* #CallyStage implements the required ATK interfaces for #ClutterStage
|
||||
*
|
||||
* Some implementation details: at this moment #CallyStage is used as
|
||||
* the most similar Window object in this toolkit (ie: emitting window
|
||||
* related signals), although the real purpose of #ClutterStage is
|
||||
* being a canvas. Anyway, this is required for applications using
|
||||
* just clutter, or directly #ClutterStage
|
||||
*/
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "cally-stage.h"
|
||||
#include "cally-actor-private.h"
|
||||
|
||||
/* AtkObject.h */
|
||||
static void cally_stage_real_initialize (AtkObject *obj,
|
||||
gpointer data);
|
||||
static AtkStateSet* cally_stage_ref_state_set (AtkObject *obj);
|
||||
|
||||
/* AtkWindow */
|
||||
static void cally_stage_window_interface_init (AtkWindowIface *iface);
|
||||
|
||||
/* Auxiliar */
|
||||
static void cally_stage_activate_cb (ClutterStage *stage,
|
||||
gpointer data);
|
||||
static void cally_stage_deactivate_cb (ClutterStage *stage,
|
||||
gpointer data);
|
||||
|
||||
struct _CallyStagePrivate
|
||||
{
|
||||
/* NULL means that the stage will receive the focus */
|
||||
ClutterActor *key_focus;
|
||||
|
||||
gboolean active;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (CallyStage,
|
||||
cally_stage,
|
||||
CALLY_TYPE_GROUP,
|
||||
G_ADD_PRIVATE (CallyStage)
|
||||
G_IMPLEMENT_INTERFACE (ATK_TYPE_WINDOW,
|
||||
cally_stage_window_interface_init));
|
||||
|
||||
static void
|
||||
cally_stage_class_init (CallyStageClass *klass)
|
||||
{
|
||||
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
|
||||
|
||||
/* AtkObject */
|
||||
class->initialize = cally_stage_real_initialize;
|
||||
class->ref_state_set = cally_stage_ref_state_set;
|
||||
}
|
||||
|
||||
static void
|
||||
cally_stage_init (CallyStage *cally_stage)
|
||||
{
|
||||
CallyStagePrivate *priv = cally_stage_get_instance_private (cally_stage);
|
||||
|
||||
cally_stage->priv = priv;
|
||||
|
||||
priv->active = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* cally_stage_new:
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* Creates a new #CallyStage for the given @actor. @actor should be a
|
||||
* #ClutterStage.
|
||||
*
|
||||
* Return value: the newly created #AtkObject
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
AtkObject*
|
||||
cally_stage_new (ClutterActor *actor)
|
||||
{
|
||||
GObject *object = NULL;
|
||||
AtkObject *accessible = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_STAGE (actor), NULL);
|
||||
|
||||
object = g_object_new (CALLY_TYPE_STAGE, NULL);
|
||||
|
||||
accessible = ATK_OBJECT (object);
|
||||
atk_object_initialize (accessible, actor);
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
static void
|
||||
cally_stage_notify_key_focus_cb (ClutterStage *stage,
|
||||
GParamSpec *pspec,
|
||||
CallyStage *self)
|
||||
{
|
||||
ClutterActor *key_focus = NULL;
|
||||
AtkObject *new = NULL;
|
||||
|
||||
if (self->priv->active == FALSE)
|
||||
return;
|
||||
|
||||
key_focus = clutter_stage_get_key_focus (stage);
|
||||
|
||||
if (key_focus != self->priv->key_focus)
|
||||
{
|
||||
AtkObject *old = NULL;
|
||||
|
||||
if (self->priv->key_focus != NULL)
|
||||
{
|
||||
g_object_remove_weak_pointer (G_OBJECT (self->priv->key_focus),
|
||||
(gpointer *) &self->priv->key_focus);
|
||||
old = clutter_actor_get_accessible (self->priv->key_focus);
|
||||
}
|
||||
else
|
||||
old = clutter_actor_get_accessible (CLUTTER_ACTOR (stage));
|
||||
|
||||
atk_object_notify_state_change (old,
|
||||
ATK_STATE_FOCUSED,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
/* we keep notifying the focus gain without checking previous
|
||||
* key-focus to avoid some missing events due timing
|
||||
*/
|
||||
self->priv->key_focus = key_focus;
|
||||
|
||||
if (key_focus != NULL)
|
||||
{
|
||||
/* ensure that if the key focus goes away, the field inside
|
||||
* CallyStage is reset. see bug:
|
||||
*
|
||||
* https://bugzilla.gnome.org/show_bug.cgi?id=692706
|
||||
*
|
||||
* we remove the weak pointer above.
|
||||
*/
|
||||
g_object_add_weak_pointer (G_OBJECT (self->priv->key_focus),
|
||||
(gpointer *) &self->priv->key_focus);
|
||||
|
||||
new = clutter_actor_get_accessible (key_focus);
|
||||
}
|
||||
else
|
||||
new = clutter_actor_get_accessible (CLUTTER_ACTOR (stage));
|
||||
|
||||
atk_object_notify_state_change (new,
|
||||
ATK_STATE_FOCUSED,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
cally_stage_real_initialize (AtkObject *obj,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterStage *stage = NULL;
|
||||
|
||||
g_return_if_fail (CALLY_IS_STAGE (obj));
|
||||
|
||||
ATK_OBJECT_CLASS (cally_stage_parent_class)->initialize (obj, data);
|
||||
|
||||
stage = CLUTTER_STAGE (CALLY_GET_CLUTTER_ACTOR (obj));
|
||||
|
||||
g_signal_connect (stage, "activate", G_CALLBACK (cally_stage_activate_cb), obj);
|
||||
g_signal_connect (stage, "deactivate", G_CALLBACK (cally_stage_deactivate_cb), obj);
|
||||
g_signal_connect (stage, "notify::key-focus",
|
||||
G_CALLBACK (cally_stage_notify_key_focus_cb), obj);
|
||||
|
||||
atk_object_set_role (obj, ATK_ROLE_WINDOW);
|
||||
}
|
||||
|
||||
static AtkStateSet*
|
||||
cally_stage_ref_state_set (AtkObject *obj)
|
||||
{
|
||||
CallyStage *cally_stage = NULL;
|
||||
AtkStateSet *state_set = NULL;
|
||||
ClutterStage *stage = NULL;
|
||||
|
||||
g_return_val_if_fail (CALLY_IS_STAGE (obj), NULL);
|
||||
cally_stage = CALLY_STAGE (obj);
|
||||
|
||||
state_set = ATK_OBJECT_CLASS (cally_stage_parent_class)->ref_state_set (obj);
|
||||
stage = CLUTTER_STAGE (CALLY_GET_CLUTTER_ACTOR (cally_stage));
|
||||
|
||||
if (stage == NULL)
|
||||
return state_set;
|
||||
|
||||
if (cally_stage->priv->active)
|
||||
atk_state_set_add_state (state_set, ATK_STATE_ACTIVE);
|
||||
|
||||
return state_set;
|
||||
}
|
||||
|
||||
/* AtkWindow */
|
||||
static void
|
||||
cally_stage_window_interface_init (AtkWindowIface *iface)
|
||||
{
|
||||
/* At this moment AtkWindow is just about signals */
|
||||
}
|
||||
|
||||
/* Auxiliar */
|
||||
static void
|
||||
cally_stage_activate_cb (ClutterStage *stage,
|
||||
gpointer data)
|
||||
{
|
||||
CallyStage *cally_stage = NULL;
|
||||
|
||||
g_return_if_fail (CALLY_IS_STAGE (data));
|
||||
|
||||
cally_stage = CALLY_STAGE (data);
|
||||
|
||||
cally_stage->priv->active = TRUE;
|
||||
|
||||
atk_object_notify_state_change (ATK_OBJECT (cally_stage),
|
||||
ATK_STATE_ACTIVE, TRUE);
|
||||
|
||||
g_signal_emit_by_name (cally_stage, "activate", 0);
|
||||
}
|
||||
|
||||
static void
|
||||
cally_stage_deactivate_cb (ClutterStage *stage,
|
||||
gpointer data)
|
||||
{
|
||||
CallyStage *cally_stage = NULL;
|
||||
|
||||
g_return_if_fail (CALLY_IS_STAGE (data));
|
||||
|
||||
cally_stage = CALLY_STAGE (data);
|
||||
|
||||
cally_stage->priv->active = FALSE;
|
||||
|
||||
atk_object_notify_state_change (ATK_OBJECT (cally_stage),
|
||||
ATK_STATE_ACTIVE, FALSE);
|
||||
|
||||
g_signal_emit_by_name (cally_stage, "deactivate", 0);
|
||||
}
|
||||
84
clutter/clutter/cally/cally-stage.h
Normal file
84
clutter/clutter/cally/cally-stage.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CALLY_STAGE_H__
|
||||
#define __CALLY_STAGE_H__
|
||||
|
||||
#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <cally/cally.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <cally/cally-group.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CALLY_TYPE_STAGE (cally_stage_get_type ())
|
||||
#define CALLY_STAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_STAGE, CallyStage))
|
||||
#define CALLY_STAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_STAGE, CallyStageClass))
|
||||
#define CALLY_IS_STAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_STAGE))
|
||||
#define CALLY_IS_STAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_STAGE))
|
||||
#define CALLY_STAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_STAGE, CallyStageClass))
|
||||
|
||||
typedef struct _CallyStage CallyStage;
|
||||
typedef struct _CallyStageClass CallyStageClass;
|
||||
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
|
||||
{
|
||||
/*< private >*/
|
||||
CallyGroup parent;
|
||||
|
||||
CallyStagePrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* CallyStageClass:
|
||||
*
|
||||
* The <structname>CallyStageClass</structname> structure contains only
|
||||
* private data
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _CallyStageClass
|
||||
{
|
||||
/*< private >*/
|
||||
CallyGroupClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[16];
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType cally_stage_get_type (void) G_GNUC_CONST;
|
||||
CLUTTER_EXPORT
|
||||
AtkObject *cally_stage_new (ClutterActor *actor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CALLY_STAGE_H__ */
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Clutter.
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2009 Igalia, S.L.
|
||||
*
|
||||
@@ -23,36 +23,43 @@
|
||||
* 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/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterTextAccessible:
|
||||
* SECTION:cally-text
|
||||
* @short_description: Implementation of the ATK interfaces for a #ClutterText
|
||||
* @see_also: #ClutterText
|
||||
*
|
||||
* #CallyText implements the required ATK interfaces of
|
||||
* #ClutterText, #AtkText and #AtkEditableText
|
||||
*
|
||||
* Implementation of the ATK interfaces for a [class@Clutter.Text]
|
||||
*
|
||||
* #ClutterTextAccessible implements the required ATK interfaces of
|
||||
* [class@Clutter.Text], #AtkText and #AtkEditableText
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter/pango/clutter-text-accessible-private.h"
|
||||
#include "cally-text.h"
|
||||
#include "cally-actor-private.h"
|
||||
|
||||
#include "clutter/clutter-actor-private.h"
|
||||
#include "clutter/clutter-main.h"
|
||||
#include "clutter/pango/clutter-text.h"
|
||||
#include "clutter-color.h"
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-text.h"
|
||||
|
||||
static void cally_text_finalize (GObject *obj);
|
||||
|
||||
/* AtkObject */
|
||||
static void cally_text_real_initialize (AtkObject *obj,
|
||||
gpointer data);
|
||||
static AtkStateSet* cally_text_ref_state_set (AtkObject *obj);
|
||||
|
||||
/* atkaction */
|
||||
|
||||
static void _cally_text_activate_action (ClutterActorAccessible *accessible_actor);
|
||||
static void _check_activate_action (ClutterTextAccessible *self,
|
||||
ClutterText *clutter_text);
|
||||
static void _cally_text_activate_action (CallyActor *cally_actor);
|
||||
static void _check_activate_action (CallyText *cally_text,
|
||||
ClutterText *clutter_text);
|
||||
|
||||
/* AtkText */
|
||||
static void cally_text_text_interface_init (AtkTextIface *iface);
|
||||
@@ -124,8 +131,8 @@ static void _cally_text_delete_text_cb (ClutterText *c
|
||||
gint end_pos,
|
||||
gpointer data);
|
||||
static gboolean _idle_notify_insert (gpointer data);
|
||||
static void _notify_insert (ClutterTextAccessible *cally_text);
|
||||
static void _notify_delete (ClutterTextAccessible *cally_text);
|
||||
static void _notify_insert (CallyText *cally_text);
|
||||
static void _notify_delete (CallyText *cally_text);
|
||||
|
||||
/* AtkEditableText */
|
||||
static void cally_text_editable_text_interface_init (AtkEditableTextIface *iface);
|
||||
@@ -139,11 +146,12 @@ static void cally_text_delete_text (AtkEditable
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
|
||||
/* CallyActor */
|
||||
static void cally_text_notify_clutter (GObject *obj,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static gboolean _check_for_selection_change (ClutterTextAccessible *cally_text,
|
||||
ClutterText *clutter_text);
|
||||
static gboolean _check_for_selection_change (CallyText *cally_text,
|
||||
ClutterText *clutter_text);
|
||||
|
||||
/* Misc functions */
|
||||
static AtkAttributeSet* _cally_misc_add_attribute (AtkAttributeSet *attrib_set,
|
||||
@@ -164,46 +172,8 @@ static int _cally_misc_get_index_at_point (ClutterText *clutter
|
||||
gint y,
|
||||
AtkCoordType coords);
|
||||
|
||||
/* AtkAction.h */
|
||||
static void cally_text_action_interface_init (AtkActionIface *iface);
|
||||
|
||||
static gboolean cally_text_action_do_action (AtkAction *action,
|
||||
gint i);
|
||||
|
||||
static gint cally_text_action_get_n_actions (AtkAction *action);
|
||||
|
||||
static const gchar * cally_text_action_get_name (AtkAction *action,
|
||||
gint i);
|
||||
|
||||
/**
|
||||
* ClutterActorActionFunc:
|
||||
* @accessible_actor: a #ClutterActorAccessible
|
||||
*
|
||||
* Action function, to be used on #AtkAction implementations as a individual
|
||||
* action
|
||||
*/
|
||||
typedef void (* ClutterActorActionFunc) (ClutterActorAccessible *accessible_actor);
|
||||
|
||||
/*< private >
|
||||
* ClutterTextAccessibleActionInfo:
|
||||
* @name: name of the action
|
||||
* @do_action_func: callback
|
||||
*
|
||||
* Utility structure to maintain the different actions added to the
|
||||
* #ClutterActorAcessible
|
||||
*/
|
||||
typedef struct _ClutterTextAccessibleActionInfo
|
||||
struct _CallyTextPrivate
|
||||
{
|
||||
gchar *name;
|
||||
|
||||
ClutterActorActionFunc do_action_func;
|
||||
} ClutterTextAccessibleActionInfo;
|
||||
|
||||
|
||||
struct _ClutterTextAccessible
|
||||
{
|
||||
ClutterActorAccessible parent;
|
||||
|
||||
/* Cached ClutterText values*/
|
||||
gint cursor_position;
|
||||
gint selection_bound;
|
||||
@@ -220,59 +190,97 @@ struct _ClutterTextAccessible
|
||||
gint length_delete;
|
||||
|
||||
/* action */
|
||||
ClutterTextAccessibleActionInfo *activate_action;
|
||||
GQueue *action_queue;
|
||||
guint action_idle_handler;
|
||||
guint activate_action_id;
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE_WITH_CODE (ClutterTextAccessible,
|
||||
clutter_text_accessible,
|
||||
CLUTTER_TYPE_ACTOR_ACCESSIBLE,
|
||||
G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT,
|
||||
cally_text_text_interface_init)
|
||||
G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION,
|
||||
cally_text_action_interface_init)
|
||||
G_IMPLEMENT_INTERFACE (ATK_TYPE_EDITABLE_TEXT,
|
||||
cally_text_editable_text_interface_init));
|
||||
G_DEFINE_TYPE_WITH_CODE (CallyText,
|
||||
cally_text,
|
||||
CALLY_TYPE_ACTOR,
|
||||
G_ADD_PRIVATE (CallyText)
|
||||
G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT,
|
||||
cally_text_text_interface_init)
|
||||
G_IMPLEMENT_INTERFACE (ATK_TYPE_EDITABLE_TEXT,
|
||||
cally_text_editable_text_interface_init));
|
||||
|
||||
static void
|
||||
clutter_text_accessible_class_init (ClutterTextAccessibleClass *klass)
|
||||
cally_text_class_init (CallyTextClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
|
||||
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
|
||||
CallyActorClass *cally_class = CALLY_ACTOR_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = cally_text_finalize;
|
||||
|
||||
class->initialize = cally_text_real_initialize;
|
||||
class->ref_state_set = cally_text_ref_state_set;
|
||||
|
||||
cally_class->notify_clutter = cally_text_notify_clutter;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_text_accessible_init (ClutterTextAccessible *self)
|
||||
cally_text_init (CallyText *cally_text)
|
||||
{
|
||||
self->cursor_position = 0;
|
||||
self->selection_bound = 0;
|
||||
CallyTextPrivate *priv = cally_text_get_instance_private (cally_text);
|
||||
|
||||
self->signal_name_insert = NULL;
|
||||
self->position_insert = -1;
|
||||
self->length_insert = -1;
|
||||
self->insert_idle_handler = 0;
|
||||
cally_text->priv = priv;
|
||||
|
||||
self->signal_name_delete = NULL;
|
||||
self->position_delete = -1;
|
||||
self->length_delete = -1;
|
||||
self->action_queue = g_queue_new ();
|
||||
priv->cursor_position = 0;
|
||||
priv->selection_bound = 0;
|
||||
|
||||
priv->signal_name_insert = NULL;
|
||||
priv->position_insert = -1;
|
||||
priv->length_insert = -1;
|
||||
priv->insert_idle_handler = 0;
|
||||
|
||||
priv->signal_name_delete = NULL;
|
||||
priv->position_delete = -1;
|
||||
priv->length_delete = -1;
|
||||
|
||||
priv->activate_action_id = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
cally_text_finalize (GObject *obj)
|
||||
{
|
||||
ClutterTextAccessible *self = CLUTTER_TEXT_ACCESSIBLE (obj);
|
||||
CallyText *cally_text = CALLY_TEXT (obj);
|
||||
|
||||
g_clear_handle_id (&self->insert_idle_handler, g_source_remove);
|
||||
g_clear_handle_id (&self->action_idle_handler, g_source_remove);
|
||||
g_clear_pointer (&self->action_queue, g_queue_free);
|
||||
/* g_object_unref (cally_text->priv->textutil); */
|
||||
/* cally_text->priv->textutil = NULL; */
|
||||
|
||||
G_OBJECT_CLASS (clutter_text_accessible_parent_class)->finalize (obj);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* cally_text_new:
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* Creates a new #CallyText for the given @actor. @actor must be a
|
||||
* #ClutterText.
|
||||
*
|
||||
* Return value: the newly created #AtkObject
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
AtkObject*
|
||||
cally_text_new (ClutterActor *actor)
|
||||
{
|
||||
GObject *object = NULL;
|
||||
AtkObject *accessible = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_TEXT (actor), NULL);
|
||||
|
||||
object = g_object_new (CALLY_TYPE_TEXT, NULL);
|
||||
|
||||
accessible = ATK_OBJECT (object);
|
||||
atk_object_initialize (accessible, actor);
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
/* atkobject.h */
|
||||
@@ -282,31 +290,26 @@ cally_text_real_initialize(AtkObject *obj,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterText *clutter_text = NULL;
|
||||
ClutterTextAccessible *self = NULL;
|
||||
CallyText *cally_text = NULL;
|
||||
|
||||
ATK_OBJECT_CLASS (clutter_text_accessible_parent_class)->initialize (obj, data);
|
||||
ATK_OBJECT_CLASS (cally_text_parent_class)->initialize (obj, data);
|
||||
|
||||
g_return_if_fail (CLUTTER_TEXT (data));
|
||||
|
||||
self = CLUTTER_TEXT_ACCESSIBLE (obj);
|
||||
cally_text = CALLY_TEXT (obj);
|
||||
clutter_text = CLUTTER_TEXT (data);
|
||||
|
||||
self->cursor_position = clutter_text_get_cursor_position (clutter_text);
|
||||
self->selection_bound = clutter_text_get_selection_bound (clutter_text);
|
||||
|
||||
g_signal_connect (clutter_text,
|
||||
"notify",
|
||||
G_CALLBACK (cally_text_notify_clutter),
|
||||
NULL);
|
||||
cally_text->priv->cursor_position = clutter_text_get_cursor_position (clutter_text);
|
||||
cally_text->priv->selection_bound = clutter_text_get_selection_bound (clutter_text);
|
||||
|
||||
g_signal_connect (clutter_text, "insert-text",
|
||||
G_CALLBACK (_cally_text_insert_text_cb),
|
||||
self);
|
||||
cally_text);
|
||||
g_signal_connect (clutter_text, "delete-text",
|
||||
G_CALLBACK (_cally_text_delete_text_cb),
|
||||
self);
|
||||
cally_text);
|
||||
|
||||
_check_activate_action (self, clutter_text);
|
||||
_check_activate_action (cally_text, clutter_text);
|
||||
|
||||
if (clutter_text_get_password_char (clutter_text) != 0)
|
||||
atk_object_set_role (obj, ATK_ROLE_PASSWORD_TEXT);
|
||||
@@ -314,6 +317,28 @@ cally_text_real_initialize(AtkObject *obj,
|
||||
atk_object_set_role (obj, ATK_ROLE_TEXT);
|
||||
}
|
||||
|
||||
static AtkStateSet*
|
||||
cally_text_ref_state_set (AtkObject *obj)
|
||||
{
|
||||
AtkStateSet *result = NULL;
|
||||
ClutterActor *actor = NULL;
|
||||
|
||||
result = ATK_OBJECT_CLASS (cally_text_parent_class)->ref_state_set (obj);
|
||||
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (obj);
|
||||
|
||||
if (actor == NULL)
|
||||
return result;
|
||||
|
||||
if (clutter_text_get_editable (CLUTTER_TEXT (actor)))
|
||||
atk_state_set_add_state (result, ATK_STATE_EDITABLE);
|
||||
|
||||
if (clutter_text_get_selectable (CLUTTER_TEXT (actor)))
|
||||
atk_state_set_add_state (result, ATK_STATE_SELECTABLE_TEXT);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/***** pango stuff ****
|
||||
*
|
||||
* FIXME: all this pango related code used to implement
|
||||
@@ -720,7 +745,7 @@ pango_layout_get_line_after (PangoLayout *layout,
|
||||
*
|
||||
* The @boundary_type determines the size of the returned slice of
|
||||
* text. For the exact semantics of this function, see
|
||||
* [method@Atk.Text.get_text_after_offset].
|
||||
* atk_text_get_text_after_offset().
|
||||
*
|
||||
* Returns: a newly allocated string containing a slice of text
|
||||
* from layout. Free with g_free().
|
||||
@@ -819,7 +844,7 @@ _gtk_pango_get_text_at (PangoLayout *layout,
|
||||
*
|
||||
* The @boundary_type determines the size of the returned slice of
|
||||
* text. For the exact semantics of this function, see
|
||||
* [method@Atk.Text.get_text_before_offset].
|
||||
* atk_text_get_text_before_offset().
|
||||
*
|
||||
* Returns: a newly allocated string containing a slice of text
|
||||
* from layout. Free with g_free().
|
||||
@@ -920,7 +945,7 @@ _gtk_pango_get_text_before (PangoLayout *layout,
|
||||
*
|
||||
* The @boundary_type determines the size of the returned slice of
|
||||
* text. For the exact semantics of this function, see
|
||||
* [method@Atk.Text.get_text_after_offset].
|
||||
* atk_text_get_text_after_offset().
|
||||
*
|
||||
* Returns: a newly allocated string containing a slice of text
|
||||
* from layout. Free with g_free().
|
||||
@@ -1052,7 +1077,7 @@ cally_text_get_text (AtkText *text,
|
||||
const gchar *string = NULL;
|
||||
gint character_count = 0;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL) /* Object is defunct */
|
||||
return NULL;
|
||||
|
||||
@@ -1082,7 +1107,7 @@ cally_text_get_character_at_offset (AtkText *text,
|
||||
gunichar unichar;
|
||||
PangoLayout *layout = NULL;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return '\0';
|
||||
|
||||
@@ -1115,7 +1140,7 @@ cally_text_get_text_before_offset (AtkText *text,
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return NULL;
|
||||
|
||||
@@ -1133,7 +1158,7 @@ cally_text_get_text_at_offset (AtkText *text,
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return NULL;
|
||||
|
||||
@@ -1151,7 +1176,7 @@ cally_text_get_text_after_offset (AtkText *text,
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return NULL;
|
||||
|
||||
@@ -1163,21 +1188,13 @@ cally_text_get_text_after_offset (AtkText *text,
|
||||
static gint
|
||||
cally_text_get_caret_offset (AtkText *text)
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
ClutterTextBuffer *buffer;
|
||||
int cursor_pos;
|
||||
ClutterActor *actor = NULL;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return -1;
|
||||
|
||||
cursor_pos = clutter_text_get_cursor_position (CLUTTER_TEXT (actor));
|
||||
if (cursor_pos >= 0)
|
||||
return cursor_pos;
|
||||
|
||||
/* Cursor is at end */
|
||||
buffer = clutter_text_get_buffer (CLUTTER_TEXT (actor));
|
||||
return clutter_text_buffer_get_length (buffer);
|
||||
return clutter_text_get_cursor_position (CLUTTER_TEXT (actor));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1186,7 +1203,7 @@ cally_text_set_caret_offset (AtkText *text,
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return FALSE;
|
||||
|
||||
@@ -1203,7 +1220,7 @@ cally_text_get_character_count (AtkText *text)
|
||||
ClutterActor *actor = NULL;
|
||||
ClutterText *clutter_text = NULL;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return 0;
|
||||
|
||||
@@ -1218,7 +1235,7 @@ cally_text_get_n_selections (AtkText *text)
|
||||
gint selection_bound = -1;
|
||||
gint cursor_position = -1;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return 0;
|
||||
|
||||
@@ -1242,7 +1259,7 @@ cally_text_get_selection (AtkText *text,
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return NULL;
|
||||
|
||||
@@ -1271,7 +1288,7 @@ cally_text_add_selection (AtkText *text,
|
||||
ClutterActor *actor;
|
||||
gint select_start, select_end;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return FALSE;
|
||||
|
||||
@@ -1302,7 +1319,7 @@ cally_text_remove_selection (AtkText *text,
|
||||
gint select_start = -1;
|
||||
gint select_end = -1;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return FALSE;
|
||||
|
||||
@@ -1337,7 +1354,7 @@ cally_text_set_selection (AtkText *text,
|
||||
gint select_start = -1;
|
||||
gint select_end = -1;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return FALSE;
|
||||
|
||||
@@ -1370,7 +1387,7 @@ cally_text_get_run_attributes (AtkText *text,
|
||||
ClutterText *clutter_text = NULL;
|
||||
AtkAttributeSet *at_set = NULL;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return NULL;
|
||||
|
||||
@@ -1394,7 +1411,7 @@ cally_text_get_default_attributes (AtkText *text)
|
||||
ClutterText *clutter_text = NULL;
|
||||
AtkAttributeSet *at_set = NULL;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return NULL;
|
||||
|
||||
@@ -1416,14 +1433,14 @@ static void cally_text_get_character_extents (AtkText *text,
|
||||
ClutterActor *actor = NULL;
|
||||
ClutterText *clutter_text = NULL;
|
||||
gint x = 0, y = 0, width = 0, height = 0;
|
||||
gint index, x_window, y_window;
|
||||
gint index, x_window, y_window, x_toplevel, y_toplevel;
|
||||
gint x_layout, y_layout;
|
||||
PangoLayout *layout;
|
||||
PangoRectangle extents;
|
||||
const gchar *text_value;
|
||||
graphene_point3d_t verts[4];
|
||||
ClutterVertex verts[4];
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
goto done;
|
||||
|
||||
@@ -1443,8 +1460,8 @@ static void cally_text_get_character_extents (AtkText *text,
|
||||
}
|
||||
|
||||
clutter_actor_get_abs_allocation_vertices (actor, verts);
|
||||
x_window = (int) verts[0].x;
|
||||
y_window = (int) verts[0].y;
|
||||
x_window = verts[0].x;
|
||||
y_window = verts[0].y;
|
||||
|
||||
clutter_text_get_layout_offsets (clutter_text, &x_layout, &y_layout);
|
||||
|
||||
@@ -1453,6 +1470,13 @@ static void cally_text_get_character_extents (AtkText *text,
|
||||
width = extents.width / PANGO_SCALE;
|
||||
height = extents.height / PANGO_SCALE;
|
||||
|
||||
if (coords == ATK_XY_SCREEN)
|
||||
{
|
||||
_cally_actor_get_top_level_origin (actor, &x_toplevel, &y_toplevel);
|
||||
x += x_toplevel;
|
||||
y += y_toplevel;
|
||||
}
|
||||
|
||||
done:
|
||||
if (widthp)
|
||||
*widthp = width;
|
||||
@@ -1478,7 +1502,7 @@ cally_text_get_offset_at_point (AtkText *text,
|
||||
const gchar *text_value;
|
||||
gint index;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return -1;
|
||||
|
||||
@@ -1493,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
|
||||
bound, but this could be before or after the cursor. This method returns
|
||||
@@ -1528,24 +1552,24 @@ _cally_text_delete_text_cb (ClutterText *clutter_text,
|
||||
gint end_pos,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterTextAccessible *self = NULL;
|
||||
CallyText *cally_text = NULL;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_TEXT_ACCESSIBLE (data));
|
||||
g_return_if_fail (CALLY_IS_TEXT (data));
|
||||
|
||||
/* Ignore zero length deletions */
|
||||
/* Ignore zero lengh deletions */
|
||||
if (end_pos - start_pos == 0)
|
||||
return;
|
||||
|
||||
self = CLUTTER_TEXT_ACCESSIBLE (data);
|
||||
cally_text = CALLY_TEXT (data);
|
||||
|
||||
if (!self->signal_name_delete)
|
||||
if (!cally_text->priv->signal_name_delete)
|
||||
{
|
||||
self->signal_name_delete = "text_changed::delete";
|
||||
self->position_delete = start_pos;
|
||||
self->length_delete = end_pos - start_pos;
|
||||
cally_text->priv->signal_name_delete = "text_changed::delete";
|
||||
cally_text->priv->position_delete = start_pos;
|
||||
cally_text->priv->length_delete = end_pos - start_pos;
|
||||
}
|
||||
|
||||
_notify_delete (self);
|
||||
_notify_delete (cally_text);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1555,25 +1579,26 @@ _cally_text_insert_text_cb (ClutterText *clutter_text,
|
||||
gint *position,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterTextAccessible *self = NULL;
|
||||
CallyText *cally_text = NULL;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_TEXT_ACCESSIBLE (data));
|
||||
g_return_if_fail (CALLY_IS_TEXT (data));
|
||||
|
||||
self = CLUTTER_TEXT_ACCESSIBLE (data);
|
||||
cally_text = CALLY_TEXT (data);
|
||||
|
||||
if (!self->signal_name_insert)
|
||||
if (!cally_text->priv->signal_name_insert)
|
||||
{
|
||||
self->signal_name_insert = "text_changed::insert";
|
||||
self->position_insert = *position;
|
||||
self->length_insert = g_utf8_strlen (new_text, new_text_length);
|
||||
cally_text->priv->signal_name_insert = "text_changed::insert";
|
||||
cally_text->priv->position_insert = *position;
|
||||
cally_text->priv->length_insert = g_utf8_strlen (new_text, new_text_length);
|
||||
}
|
||||
|
||||
/*
|
||||
* The signal will be emitted when the cursor position is updated,
|
||||
* or in an idle handler if it not updated.
|
||||
*/
|
||||
if (self->insert_idle_handler == 0)
|
||||
self->insert_idle_handler = g_idle_add (_idle_notify_insert, self);
|
||||
if (cally_text->priv->insert_idle_handler == 0)
|
||||
cally_text->priv->insert_idle_handler = clutter_threads_add_idle (_idle_notify_insert,
|
||||
cally_text);
|
||||
}
|
||||
|
||||
/***** atkeditabletext.h ******/
|
||||
@@ -1599,7 +1624,7 @@ cally_text_set_text_contents (AtkEditableText *text,
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL)
|
||||
return;
|
||||
|
||||
@@ -1619,7 +1644,7 @@ cally_text_insert_text (AtkEditableText *text,
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL)
|
||||
return;
|
||||
|
||||
@@ -1632,7 +1657,7 @@ cally_text_insert_text (AtkEditableText *text,
|
||||
clutter_text_insert_text (CLUTTER_TEXT (actor),
|
||||
string, *position);
|
||||
|
||||
/* we suppose that the text insertion will be successful,
|
||||
/* we suppose that the text insertion will be succesful,
|
||||
clutter-text doesn't warn about it. A option would be search for
|
||||
the text, but it seems not really required */
|
||||
*position += length;
|
||||
@@ -1644,7 +1669,7 @@ static void cally_text_delete_text (AtkEditableText *text,
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (text);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (text);
|
||||
if (actor == NULL)
|
||||
return;
|
||||
|
||||
@@ -1655,22 +1680,23 @@ static void cally_text_delete_text (AtkEditableText *text,
|
||||
start_pos, end_pos);
|
||||
}
|
||||
|
||||
/* CallyActor */
|
||||
static void
|
||||
cally_text_notify_clutter (GObject *obj,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterText *clutter_text = NULL;
|
||||
ClutterTextAccessible *self = NULL;
|
||||
CallyText *cally_text = NULL;
|
||||
AtkObject *atk_obj = NULL;
|
||||
|
||||
clutter_text = CLUTTER_TEXT (obj);
|
||||
atk_obj = clutter_actor_get_accessible (CLUTTER_ACTOR (obj));
|
||||
self = CLUTTER_TEXT_ACCESSIBLE (atk_obj);
|
||||
cally_text = CALLY_TEXT (atk_obj);
|
||||
|
||||
if (g_strcmp0 (pspec->name, "cursor-position") == 0)
|
||||
if (g_strcmp0 (pspec->name, "position") == 0)
|
||||
{
|
||||
/* the selection can change also for the cursor position */
|
||||
if (_check_for_selection_change (self, clutter_text))
|
||||
if (_check_for_selection_change (cally_text, clutter_text))
|
||||
g_signal_emit_by_name (atk_obj, "text_selection_changed");
|
||||
|
||||
g_signal_emit_by_name (atk_obj, "text_caret_moved",
|
||||
@@ -1678,18 +1704,34 @@ cally_text_notify_clutter (GObject *obj,
|
||||
}
|
||||
else if (g_strcmp0 (pspec->name, "selection-bound") == 0)
|
||||
{
|
||||
if (_check_for_selection_change (self, clutter_text))
|
||||
if (_check_for_selection_change (cally_text, clutter_text))
|
||||
g_signal_emit_by_name (atk_obj, "text_selection_changed");
|
||||
}
|
||||
else if (g_strcmp0 (pspec->name, "editable") == 0)
|
||||
{
|
||||
atk_object_notify_state_change (atk_obj, ATK_STATE_EDITABLE,
|
||||
clutter_text_get_editable (clutter_text));
|
||||
}
|
||||
else if (g_strcmp0 (pspec->name, "activatable") == 0)
|
||||
{
|
||||
_check_activate_action (self, clutter_text);
|
||||
_check_activate_action (cally_text, clutter_text);
|
||||
}
|
||||
else if (g_strcmp0 (pspec->name, "password-char") == 0)
|
||||
{
|
||||
if (clutter_text_get_password_char (clutter_text) != 0)
|
||||
atk_object_set_role (atk_obj, ATK_ROLE_PASSWORD_TEXT);
|
||||
else
|
||||
atk_object_set_role (atk_obj, ATK_ROLE_TEXT);
|
||||
}
|
||||
else
|
||||
{
|
||||
CALLY_ACTOR_CLASS (cally_text_parent_class)->notify_clutter (obj, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_check_for_selection_change (ClutterTextAccessible *self,
|
||||
ClutterText *clutter_text)
|
||||
_check_for_selection_change (CallyText *cally_text,
|
||||
ClutterText *clutter_text)
|
||||
{
|
||||
gboolean ret_val = FALSE;
|
||||
gint clutter_pos = -1;
|
||||
@@ -1700,8 +1742,8 @@ _check_for_selection_change (ClutterTextAccessible *self,
|
||||
|
||||
if (clutter_pos != clutter_bound)
|
||||
{
|
||||
if (clutter_pos != self->cursor_position ||
|
||||
clutter_bound != self->selection_bound)
|
||||
if (clutter_pos != cally_text->priv->cursor_position ||
|
||||
clutter_bound != cally_text->priv->selection_bound)
|
||||
/*
|
||||
* This check is here as this function can be called for
|
||||
* notification of selection_bound and current_pos. The
|
||||
@@ -1714,11 +1756,11 @@ _check_for_selection_change (ClutterTextAccessible *self,
|
||||
else
|
||||
{
|
||||
/* We had a selection */
|
||||
ret_val = (self->cursor_position != self->selection_bound);
|
||||
ret_val = (cally_text->priv->cursor_position != cally_text->priv->selection_bound);
|
||||
}
|
||||
|
||||
self->cursor_position = clutter_pos;
|
||||
self->selection_bound = clutter_bound;
|
||||
cally_text->priv->cursor_position = clutter_pos;
|
||||
cally_text->priv->selection_bound = clutter_bound;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
@@ -1726,167 +1768,80 @@ _check_for_selection_change (ClutterTextAccessible *self,
|
||||
static gboolean
|
||||
_idle_notify_insert (gpointer data)
|
||||
{
|
||||
ClutterTextAccessible *self = CLUTTER_TEXT_ACCESSIBLE (data);
|
||||
self->insert_idle_handler = 0;
|
||||
CallyText *cally_text = NULL;
|
||||
|
||||
_notify_insert (self);
|
||||
cally_text = CALLY_TEXT (data);
|
||||
cally_text->priv->insert_idle_handler = 0;
|
||||
|
||||
_notify_insert (cally_text);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_notify_insert (ClutterTextAccessible *self)
|
||||
_notify_insert (CallyText *cally_text)
|
||||
{
|
||||
if (self->signal_name_insert)
|
||||
if (cally_text->priv->signal_name_insert)
|
||||
{
|
||||
g_signal_emit_by_name (self,
|
||||
self->signal_name_insert,
|
||||
self->position_insert,
|
||||
self->length_insert);
|
||||
self->signal_name_insert = NULL;
|
||||
g_signal_emit_by_name (cally_text,
|
||||
cally_text->priv->signal_name_insert,
|
||||
cally_text->priv->position_insert,
|
||||
cally_text->priv->length_insert);
|
||||
cally_text->priv->signal_name_insert = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_notify_delete (ClutterTextAccessible *self)
|
||||
_notify_delete (CallyText *cally_text)
|
||||
{
|
||||
if (self->signal_name_delete)
|
||||
if (cally_text->priv->signal_name_delete)
|
||||
{
|
||||
g_signal_emit_by_name (self,
|
||||
self->signal_name_delete,
|
||||
self->position_delete,
|
||||
self->length_delete);
|
||||
self->signal_name_delete = NULL;
|
||||
g_signal_emit_by_name (cally_text,
|
||||
cally_text->priv->signal_name_delete,
|
||||
cally_text->priv->position_delete,
|
||||
cally_text->priv->length_delete);
|
||||
cally_text->priv->signal_name_delete = NULL;
|
||||
}
|
||||
}
|
||||
/* atkaction */
|
||||
|
||||
static void
|
||||
_cally_text_activate_action (ClutterActorAccessible *accessible_actor)
|
||||
_cally_text_activate_action (CallyActor *cally_actor)
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (accessible_actor);
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (cally_actor);
|
||||
|
||||
clutter_text_activate (CLUTTER_TEXT (actor));
|
||||
}
|
||||
|
||||
static void
|
||||
_check_activate_action (ClutterTextAccessible *self,
|
||||
ClutterText *clutter_text)
|
||||
_check_activate_action (CallyText *cally_text,
|
||||
ClutterText *clutter_text)
|
||||
{
|
||||
|
||||
if (clutter_text_get_activatable (clutter_text))
|
||||
{
|
||||
if (self->activate_action != NULL)
|
||||
if (cally_text->priv->activate_action_id != 0)
|
||||
return;
|
||||
|
||||
self->activate_action = g_new0 (ClutterTextAccessibleActionInfo, 1);
|
||||
self->activate_action->name = g_strdup ("activate");
|
||||
self->activate_action->do_action_func = _cally_text_activate_action;
|
||||
cally_text->priv->activate_action_id = cally_actor_add_action (CALLY_ACTOR (cally_text),
|
||||
"activate", NULL, NULL,
|
||||
_cally_text_activate_action);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self->activate_action == NULL)
|
||||
if (cally_text->priv->activate_action_id == 0)
|
||||
return;
|
||||
|
||||
g_clear_pointer (&self->activate_action->name, g_free);
|
||||
g_clear_pointer (&self->activate_action, g_free);
|
||||
|
||||
if (cally_actor_remove_action (CALLY_ACTOR (cally_text),
|
||||
cally_text->priv->activate_action_id))
|
||||
{
|
||||
cally_text->priv->activate_action_id = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* AtkAction implementation */
|
||||
static void
|
||||
cally_text_action_interface_init (AtkActionIface *iface)
|
||||
{
|
||||
iface->do_action = cally_text_action_do_action;
|
||||
iface->get_n_actions = cally_text_action_get_n_actions;
|
||||
iface->get_name = cally_text_action_get_name;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
idle_do_action (gpointer data)
|
||||
{
|
||||
ClutterTextAccessible *self =
|
||||
CLUTTER_TEXT_ACCESSIBLE (data);
|
||||
self->action_idle_handler = 0;
|
||||
|
||||
/* state is defunct*/
|
||||
g_assert (CLUTTER_ACTOR_FROM_ACCESSIBLE (self) != NULL);
|
||||
|
||||
while (!g_queue_is_empty (self->action_queue))
|
||||
{
|
||||
ClutterTextAccessibleActionInfo *info = NULL;
|
||||
|
||||
info = (ClutterTextAccessibleActionInfo *) g_queue_pop_head (self->action_queue);
|
||||
|
||||
info->do_action_func (CLUTTER_ACTOR_ACCESSIBLE (self));
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cally_text_action_do_action (AtkAction *action,
|
||||
gint index)
|
||||
{
|
||||
g_autoptr (AtkStateSet) set = NULL;
|
||||
ClutterTextAccessible *self;
|
||||
|
||||
/* Only activate action is supported*/
|
||||
g_return_val_if_fail (index != 0, FALSE);
|
||||
g_return_val_if_fail (CLUTTER_IS_TEXT_ACCESSIBLE (action), FALSE);
|
||||
|
||||
self = CLUTTER_TEXT_ACCESSIBLE (action);
|
||||
|
||||
set = atk_object_ref_state_set (ATK_OBJECT (self));
|
||||
|
||||
if (atk_state_set_contains_state (set, ATK_STATE_DEFUNCT))
|
||||
return FALSE;
|
||||
|
||||
if (!atk_state_set_contains_state (set, ATK_STATE_SENSITIVE) ||
|
||||
!atk_state_set_contains_state (set, ATK_STATE_SHOWING))
|
||||
return FALSE;
|
||||
|
||||
if (self->activate_action == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (self->activate_action->do_action_func == NULL)
|
||||
return FALSE;
|
||||
|
||||
g_queue_push_head (self->action_queue, self->activate_action);
|
||||
|
||||
if (!self->action_idle_handler)
|
||||
self->action_idle_handler = g_idle_add (idle_do_action, self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gint
|
||||
cally_text_action_get_n_actions (AtkAction *action)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (action), 0);
|
||||
|
||||
/* We only support activate action*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const gchar*
|
||||
cally_text_action_get_name (AtkAction *action,
|
||||
gint i)
|
||||
{
|
||||
ClutterTextAccessible *self;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (action), NULL);
|
||||
|
||||
self = CLUTTER_TEXT_ACCESSIBLE (action);
|
||||
|
||||
if (self->activate_action == NULL)
|
||||
return NULL;
|
||||
|
||||
return self->activate_action->name;
|
||||
}
|
||||
|
||||
/* GailTextUtil/GailMisc reimplementation methods */
|
||||
|
||||
/**
|
||||
@@ -1915,7 +1870,7 @@ static gint
|
||||
_cally_atk_attribute_lookup_func (gconstpointer data,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
AtkTextAttribute attr = (AtkTextAttribute) GPOINTER_TO_INT (user_data);
|
||||
AtkTextAttribute attr = (AtkTextAttribute) user_data;
|
||||
AtkAttribute *at = (AtkAttribute *) data;
|
||||
if (!g_strcmp0 (at->name, atk_text_attribute_get_name (attr)))
|
||||
return 0;
|
||||
@@ -2064,7 +2019,7 @@ static AtkAttributeSet*
|
||||
_cally_misc_add_actor_color_to_attribute_set (AtkAttributeSet *attrib_set,
|
||||
ClutterText *clutter_text)
|
||||
{
|
||||
CoglColor color;
|
||||
ClutterColor color;
|
||||
gchar *value;
|
||||
|
||||
clutter_text_get_color (clutter_text, &color);
|
||||
@@ -2336,22 +2291,30 @@ _cally_misc_get_index_at_point (ClutterText *clutter_text,
|
||||
gint y,
|
||||
AtkCoordType coords)
|
||||
{
|
||||
gint index, x_window, y_window;
|
||||
gint index, x_window, y_window, x_toplevel, y_toplevel;
|
||||
gint x_temp, y_temp;
|
||||
gboolean ret;
|
||||
graphene_point3d_t verts[4];
|
||||
ClutterVertex verts[4];
|
||||
PangoLayout *layout;
|
||||
gint x_layout, y_layout;
|
||||
|
||||
clutter_text_get_layout_offsets (clutter_text, &x_layout, &y_layout);
|
||||
|
||||
clutter_actor_get_abs_allocation_vertices (CLUTTER_ACTOR (clutter_text), verts);
|
||||
x_window = (int) verts[0].x;
|
||||
y_window = (int) verts[0].y;
|
||||
x_window = verts[0].x;
|
||||
y_window = verts[0].y;
|
||||
|
||||
x_temp = x - x_layout - x_window;
|
||||
y_temp = y - y_layout - y_window;
|
||||
|
||||
if (coords == ATK_XY_SCREEN)
|
||||
{
|
||||
_cally_actor_get_top_level_origin (CLUTTER_ACTOR (clutter_text), &x_toplevel,
|
||||
&y_toplevel);
|
||||
x_temp -= x_toplevel;
|
||||
y_temp -= y_toplevel;
|
||||
}
|
||||
|
||||
layout = clutter_text_get_layout (clutter_text);
|
||||
ret = pango_layout_xy_to_index (layout,
|
||||
x_temp * PANGO_SCALE,
|
||||
84
clutter/clutter/cally/cally-text.h
Normal file
84
clutter/clutter/cally/cally-text.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2009 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CALLY_TEXT_H__
|
||||
#define __CALLY_TEXT_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_TEXT (cally_text_get_type ())
|
||||
#define CALLY_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_TEXT, CallyText))
|
||||
#define CALLY_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_TEXT, CallyTextClass))
|
||||
#define CALLY_IS_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_TEXT))
|
||||
#define CALLY_IS_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_TEXT))
|
||||
#define CALLY_TEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_TEXT, CallyTextClass))
|
||||
|
||||
typedef struct _CallyText CallyText;
|
||||
typedef struct _CallyTextClass CallyTextClass;
|
||||
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
|
||||
{
|
||||
/*< private >*/
|
||||
CallyActor parent;
|
||||
|
||||
CallyTextPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* CallyTextClass:
|
||||
*
|
||||
* The <structname>CallyTextClass</structname> structure contains only
|
||||
* private data
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _CallyTextClass
|
||||
{
|
||||
/*< private >*/
|
||||
CallyActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[8];
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType cally_text_get_type (void) G_GNUC_CONST;
|
||||
CLUTTER_EXPORT
|
||||
AtkObject* cally_text_new (ClutterActor *actor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CALLY_TEXT_H__ */
|
||||
98
clutter/clutter/cally/cally-texture.c
Normal file
98
clutter/clutter/cally/cally-texture.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2009 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:cally-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;
|
||||
}
|
||||
84
clutter/clutter/cally/cally-texture.h
Normal file
84
clutter/clutter/cally/cally-texture.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2009 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CALLY_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__ */
|
||||
452
clutter/clutter/cally/cally-util.c
Normal file
452
clutter/clutter/cally/cally-util.c
Normal file
@@ -0,0 +1,452 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* Based on GailUtil from GAIL
|
||||
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:cally-util
|
||||
* @Title: CallyUtil
|
||||
* @short_description: #AtkUtil implementation
|
||||
* @see_also: #ClutterActor
|
||||
*
|
||||
* #CallyUtil implements #AtkUtil abstract methods. Although it
|
||||
* includes the name "Util" it is in fact one of the most important
|
||||
* interfaces to be implemented in any ATK toolkit implementation.
|
||||
|
||||
* For instance, it defines atk_get_root(), the method that returns
|
||||
* the root object in the hierarchy. Without it, you don't have
|
||||
* available any accessible object.
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "cally-util.h"
|
||||
#include "cally-root.h"
|
||||
#include "cally-stage.h"
|
||||
|
||||
#define DEFAULT_PASSWORD_CHAR '*'
|
||||
|
||||
/* atkutil.h */
|
||||
|
||||
static guint cally_util_add_key_event_listener (AtkKeySnoopFunc listener,
|
||||
gpointer data);
|
||||
static void cally_util_remove_key_event_listener (guint remove_listener);
|
||||
static AtkObject* cally_util_get_root (void);
|
||||
static const gchar * cally_util_get_toolkit_name (void);
|
||||
static const gchar * cally_util_get_toolkit_version (void);
|
||||
|
||||
/* private */
|
||||
static 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,
|
||||
gpointer value,
|
||||
gpointer data);
|
||||
static void insert_hf (gpointer key,
|
||||
gpointer value,
|
||||
gpointer data);
|
||||
|
||||
/* This is just a copy of the Gail one, a shared library or place to
|
||||
define it could be a good idea. */
|
||||
typedef struct _CallyKeyEventInfo CallyKeyEventInfo;
|
||||
|
||||
struct _CallyKeyEventInfo
|
||||
{
|
||||
AtkKeySnoopFunc listener;
|
||||
gpointer func_data;
|
||||
};
|
||||
|
||||
static AtkObject* root = NULL;
|
||||
static GHashTable *key_listener_list = NULL;
|
||||
|
||||
|
||||
G_DEFINE_TYPE (CallyUtil, cally_util, ATK_TYPE_UTIL);
|
||||
|
||||
static void
|
||||
cally_util_class_init (CallyUtilClass *klass)
|
||||
{
|
||||
AtkUtilClass *atk_class;
|
||||
gpointer data;
|
||||
|
||||
data = g_type_class_peek (ATK_TYPE_UTIL);
|
||||
atk_class = ATK_UTIL_CLASS (data);
|
||||
|
||||
atk_class->add_key_event_listener = cally_util_add_key_event_listener;
|
||||
atk_class->remove_key_event_listener = cally_util_remove_key_event_listener;
|
||||
atk_class->get_root = cally_util_get_root;
|
||||
atk_class->get_toolkit_name = cally_util_get_toolkit_name;
|
||||
atk_class->get_toolkit_version = cally_util_get_toolkit_version;
|
||||
|
||||
/* FIXME: Instead of create this on the class, I think that would
|
||||
worth to implement CallyUtil as a singleton instance, so the
|
||||
class methods will access this instance. This will be a good
|
||||
future enhancement, meanwhile, just using the same *working*
|
||||
implementation used on GailUtil */
|
||||
}
|
||||
|
||||
static void
|
||||
cally_util_init (CallyUtil *cally_util)
|
||||
{
|
||||
/* instance init: usually not required */
|
||||
}
|
||||
|
||||
/* ------------------------------ ATK UTIL METHODS -------------------------- */
|
||||
|
||||
static AtkObject*
|
||||
cally_util_get_root (void)
|
||||
{
|
||||
if (!root)
|
||||
root = cally_root_new ();
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
cally_util_get_toolkit_name (void)
|
||||
{
|
||||
return "clutter";
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
cally_util_get_toolkit_version (void)
|
||||
{
|
||||
return MUTTER_VERSION;
|
||||
}
|
||||
|
||||
static guint
|
||||
cally_util_add_key_event_listener (AtkKeySnoopFunc listener,
|
||||
gpointer data)
|
||||
{
|
||||
static guint key = 1;
|
||||
CallyKeyEventInfo *event_info = NULL;
|
||||
|
||||
if (!key_listener_list)
|
||||
{
|
||||
key_listener_list = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
|
||||
cally_util_simulate_snooper_install ();
|
||||
}
|
||||
|
||||
event_info = g_new (CallyKeyEventInfo, 1);
|
||||
event_info->listener = listener;
|
||||
event_info->func_data = data;
|
||||
|
||||
g_hash_table_insert (key_listener_list, GUINT_TO_POINTER (key++), event_info);
|
||||
/* XXX: we don't check to see if n_listeners > MAXUINT */
|
||||
return key - 1;
|
||||
}
|
||||
|
||||
static void
|
||||
cally_util_remove_key_event_listener (guint remove_listener)
|
||||
{
|
||||
if (!g_hash_table_remove (key_listener_list, GUINT_TO_POINTER (remove_listener))) {
|
||||
g_warning ("Not able to remove listener with id %i", remove_listener);
|
||||
}
|
||||
|
||||
if (g_hash_table_size (key_listener_list) == 0)
|
||||
{
|
||||
g_hash_table_destroy (key_listener_list);
|
||||
key_listener_list = NULL;
|
||||
cally_util_simulate_snooper_remove ();
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------ 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 *
|
||||
atk_key_event_from_clutter_event_key (ClutterKeyEvent *clutter_event,
|
||||
gunichar password_char)
|
||||
{
|
||||
AtkKeyEventStruct *atk_event = g_new0 (AtkKeyEventStruct, 1);
|
||||
gunichar key_unichar;
|
||||
|
||||
switch (clutter_event->type)
|
||||
{
|
||||
case CLUTTER_KEY_PRESS:
|
||||
atk_event->type = ATK_KEY_EVENT_PRESS;
|
||||
break;
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
atk_event->type = ATK_KEY_EVENT_RELEASE;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (password_char)
|
||||
atk_event->state = 0;
|
||||
else
|
||||
atk_event->state = clutter_event->modifier_state;
|
||||
|
||||
/* We emit the clutter keyval. This is not exactly the one expected
|
||||
by AtkKeyEventStruct, as it expects a Gdk-like event, with the
|
||||
modifiers applied. But to avoid a dependency to gdk, we delegate
|
||||
that on the AT application.
|
||||
More information: Bug 1952 and bug 2072
|
||||
*/
|
||||
if (password_char)
|
||||
atk_event->keyval = clutter_unicode_to_keysym (password_char);
|
||||
else
|
||||
atk_event->keyval = clutter_event->keyval;
|
||||
|
||||
/* It is expected to store a key defining string here (ie "Space" in
|
||||
case you press a space). Anyway, there are no function on clutter
|
||||
to obtain that, and we want to avoid a gdk dependency here, so we
|
||||
delegate on the AT application to obtain that string using the
|
||||
rest of the data on the ATK event struct.
|
||||
|
||||
More information: Bug 1952 and 2072
|
||||
*/
|
||||
|
||||
if (password_char)
|
||||
key_unichar = password_char;
|
||||
else
|
||||
key_unichar = clutter_event_get_key_unicode ((ClutterEvent *) clutter_event);
|
||||
|
||||
if (g_unichar_validate (key_unichar) && !g_unichar_iscntrl (key_unichar))
|
||||
{
|
||||
GString *new = NULL;
|
||||
|
||||
new = g_string_new ("");
|
||||
new = g_string_insert_unichar (new, 0, key_unichar);
|
||||
atk_event->string = new->str;
|
||||
g_string_free (new, FALSE);
|
||||
}
|
||||
else
|
||||
atk_event->string = NULL;
|
||||
|
||||
atk_event->length = 0;
|
||||
|
||||
/* Computing the hardware keycode from the password-char is
|
||||
difficult. But we are in a password situation. We are already a
|
||||
unichar that it is not the original one. Providing a "almost
|
||||
real" keycode is irrelevant */
|
||||
if (password_char)
|
||||
atk_event->keycode = 0;
|
||||
else
|
||||
atk_event->keycode = clutter_event->hardware_keycode;
|
||||
|
||||
atk_event->timestamp = clutter_event->time;
|
||||
|
||||
#ifdef CALLY_DEBUG
|
||||
|
||||
g_debug ("CallyKeyEvent:\tsym 0x%x\n\t\tmods %x\n\t\tcode %u\n\t\ttime %lx \n\t\tstring %s\n",
|
||||
(unsigned int) atk_event->keyval,
|
||||
(unsigned int) atk_event->state,
|
||||
(unsigned int) atk_event->keycode,
|
||||
(unsigned long int) atk_event->timestamp,
|
||||
atk_event->string);
|
||||
#endif
|
||||
|
||||
return atk_event;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
notify_hf (gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
CallyKeyEventInfo *info = (CallyKeyEventInfo *) value;
|
||||
AtkKeyEventStruct *key_event = (AtkKeyEventStruct *)data;
|
||||
|
||||
return (*(AtkKeySnoopFunc) info->listener) (key_event, info->func_data) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
insert_hf (gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
GHashTable *new_table = (GHashTable *) data;
|
||||
g_hash_table_insert (new_table, key, value);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 0 if the key of that event is visible, in other case the password
|
||||
* char
|
||||
*/
|
||||
static gunichar
|
||||
check_key_visibility (ClutterEvent *event)
|
||||
{
|
||||
ClutterKeyEvent *key_event = (ClutterKeyEvent *)event;
|
||||
AtkObject *accessible = clutter_actor_get_accessible (key_event->source);
|
||||
|
||||
g_return_val_if_fail (accessible != NULL, 0);
|
||||
|
||||
if (atk_object_get_role (accessible) != ATK_ROLE_PASSWORD_TEXT)
|
||||
return 0;
|
||||
|
||||
/* If it is a clutter text, we use his password char. Note that
|
||||
although at Clutter toolkit itself, only ClutterText exposes a
|
||||
password role, nothing prevents on any derived toolkit (like st)
|
||||
to create a new actor that can behave like a password entry. And
|
||||
the key event will still be emitted here. Although in that case
|
||||
we would lose any password char from the derived toolkit, it is
|
||||
still better fill this with a default unichar that the original
|
||||
one */
|
||||
|
||||
if (CLUTTER_IS_TEXT (key_event->source))
|
||||
return clutter_text_get_password_char (CLUTTER_TEXT (key_event->source));
|
||||
else
|
||||
return DEFAULT_PASSWORD_CHAR;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cally_key_snooper (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
AtkKeyEventStruct *key_event = NULL;
|
||||
gint consumed = 0;
|
||||
gunichar password_char = 0;
|
||||
|
||||
/* filter key events */
|
||||
if ((event->type != CLUTTER_KEY_PRESS) && (event->type != CLUTTER_KEY_RELEASE))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
password_char = check_key_visibility (event);
|
||||
|
||||
if (key_listener_list)
|
||||
{
|
||||
GHashTable *new_hash = g_hash_table_new (NULL, NULL);
|
||||
|
||||
g_hash_table_foreach (key_listener_list, insert_hf, new_hash);
|
||||
key_event = atk_key_event_from_clutter_event_key ((ClutterKeyEvent *)event,
|
||||
password_char);
|
||||
/* func data is inside the hash table */
|
||||
consumed = g_hash_table_foreach_steal (new_hash, notify_hf, key_event);
|
||||
g_hash_table_destroy (new_hash);
|
||||
|
||||
g_free (key_event->string);
|
||||
g_free (key_event);
|
||||
}
|
||||
|
||||
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
|
||||
_cally_util_override_atk_util (void)
|
||||
{
|
||||
AtkUtilClass *atk_class = ATK_UTIL_CLASS (g_type_class_ref (ATK_TYPE_UTIL));
|
||||
|
||||
atk_class->add_key_event_listener = cally_util_add_key_event_listener;
|
||||
atk_class->remove_key_event_listener = cally_util_remove_key_event_listener;
|
||||
atk_class->get_root = cally_util_get_root;
|
||||
atk_class->get_toolkit_name = cally_util_get_toolkit_name;
|
||||
atk_class->get_toolkit_version = cally_util_get_toolkit_version;
|
||||
}
|
||||
84
clutter/clutter/cally/cally-util.h
Normal file
84
clutter/clutter/cally/cally-util.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CALLY_UTIL_H__
|
||||
#define __CALLY_UTIL_H__
|
||||
|
||||
#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <cally/cally.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <atk/atk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CALLY_TYPE_UTIL (cally_util_get_type ())
|
||||
#define CALLY_UTIL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_UTIL, CallyUtil))
|
||||
#define CALLY_UTIL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_UTIL, CallyUtilClass))
|
||||
#define CALLY_IS_UTIL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_UTIL))
|
||||
#define CALLY_IS_UTIL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_UTIL))
|
||||
#define CALLY_UTIL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_UTIL, CallyUtilClass))
|
||||
|
||||
typedef struct _CallyUtil CallyUtil;
|
||||
typedef struct _CallyUtilClass CallyUtilClass;
|
||||
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
|
||||
{
|
||||
/*< private >*/
|
||||
AtkUtil parent;
|
||||
|
||||
CallyUtilPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* CallyUtilClass:
|
||||
*
|
||||
* The <structname>CallyUtilClass</structname> structure contains only
|
||||
* private data
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _CallyUtilClass
|
||||
{
|
||||
/*< private >*/
|
||||
AtkUtilClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[8];
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType cally_util_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void _cally_util_override_atk_util (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CALLY_UTIL_H__ */
|
||||
106
clutter/clutter/cally/cally.c
Normal file
106
clutter/clutter/cally/cally.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:cally
|
||||
* @Title: Cally
|
||||
* @short_description: Cally initialization methods.
|
||||
*
|
||||
* Cally initialization methods.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#include "cally.h"
|
||||
|
||||
#include "cally-actor.h"
|
||||
#include "cally-group.h"
|
||||
#include "cally-stage.h"
|
||||
#include "cally-text.h"
|
||||
#include "cally-texture.h"
|
||||
#include "cally-rectangle.h"
|
||||
#include "cally-clone.h"
|
||||
|
||||
#include "cally-factory.h"
|
||||
#include "cally-util.h"
|
||||
|
||||
#include "clutter.h"
|
||||
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
/* factories initialization*/
|
||||
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_ACTOR, cally_actor, cally_actor_new)
|
||||
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_GROUP, cally_group, cally_group_new)
|
||||
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_STAGE, cally_stage, cally_stage_new)
|
||||
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_TEXT, cally_text, cally_text_new)
|
||||
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_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_accessibility_init:
|
||||
*
|
||||
* Initializes the accessibility support.
|
||||
*
|
||||
* Return value: %TRUE if accessibility support has been correctly
|
||||
* initialized.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
gboolean
|
||||
cally_accessibility_init (void)
|
||||
{
|
||||
/* setting the factories */
|
||||
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_ACTOR, cally_actor);
|
||||
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_GROUP, cally_group);
|
||||
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_STAGE, cally_stage);
|
||||
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXT, cally_text);
|
||||
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXTURE, cally_texture);
|
||||
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_RECTANGLE, cally_rectangle);
|
||||
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_CLONE, cally_clone);
|
||||
|
||||
/* Initialize the CallyUtility class */
|
||||
_cally_util_override_atk_util ();
|
||||
|
||||
CLUTTER_NOTE (MISC, "Clutter Accessibility initialized");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* cally_get_cally_initialized:
|
||||
*
|
||||
* Returns if the accessibility support using cally is enabled.
|
||||
*
|
||||
* Return value: %TRUE if accessibility support has been correctly
|
||||
* initialized.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
gboolean cally_get_cally_initialized (void)
|
||||
{
|
||||
return !g_strcmp0 (atk_get_toolkit_name (), "clutter");
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Clutter.
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
@@ -18,18 +18,23 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CALLY_H__
|
||||
#define __CALLY_H__
|
||||
|
||||
#include <atk/atk.h>
|
||||
#define __CALLY_H_INSIDE__
|
||||
|
||||
#include "clutter/clutter-macros.h"
|
||||
#include "clutter/clutter-stage.h"
|
||||
#include "cally-actor.h"
|
||||
#include "cally-clone.h"
|
||||
#include "cally-factory.h"
|
||||
#include "cally-group.h"
|
||||
#include "cally-main.h"
|
||||
#include "cally-rectangle.h"
|
||||
#include "cally-root.h"
|
||||
#include "cally-stage.h"
|
||||
#include "cally-text.h"
|
||||
#include "cally-texture.h"
|
||||
#include "cally-util.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
#undef __CALLY_H_INSIDE__
|
||||
|
||||
void _clutter_accessibility_override_atk_util (void);
|
||||
|
||||
gboolean clutter_accessibility_snoop_key_event (ClutterStage *stage,
|
||||
ClutterKeyEvent *key);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __CALLY_H__ */
|
||||
@@ -1,306 +0,0 @@
|
||||
/* Clutter.
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* Based on GailUtil from GAIL
|
||||
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "clutter/clutter-accessibility-private.h"
|
||||
#include "clutter/clutter-context-private.h"
|
||||
#include "clutter/clutter-stage-manager-accessible-private.h"
|
||||
#include "clutter/clutter.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#ifdef HAVE_FONTS
|
||||
#include "clutter/clutter-pango.h"
|
||||
#endif
|
||||
|
||||
#define DEFAULT_PASSWORD_CHAR '*'
|
||||
|
||||
/* This is just a copy of the Gail one, a shared library or place to
|
||||
define it could be a good idea. */
|
||||
typedef struct _KeyEventInfo
|
||||
{
|
||||
AtkKeySnoopFunc listener;
|
||||
gpointer func_data;
|
||||
} KeyEventInfo;
|
||||
|
||||
static AtkObject*root = NULL;
|
||||
static GHashTable *key_listener_list = NULL;
|
||||
|
||||
/* ------------------------------ ATK UTIL METHODS -------------------------- */
|
||||
|
||||
static AtkObject*
|
||||
clutter_accessibility_get_root (void)
|
||||
{
|
||||
ClutterContext *context = _clutter_context_get_default ();
|
||||
ClutterStageManager *stage_manager =
|
||||
clutter_context_get_stage_manager (context);
|
||||
|
||||
if (!root)
|
||||
root = clutter_stage_manager_accessible_new (stage_manager);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
clutter_accessibility_get_toolkit_name (void)
|
||||
{
|
||||
return "clutter";
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
clutter_accessibility_get_toolkit_version (void)
|
||||
{
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
static guint
|
||||
clutter_accessibility_add_key_event_listener (AtkKeySnoopFunc listener,
|
||||
gpointer data)
|
||||
{
|
||||
static guint key = 1;
|
||||
KeyEventInfo *event_info = NULL;
|
||||
|
||||
if (!key_listener_list)
|
||||
key_listener_list = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
|
||||
event_info = g_new (KeyEventInfo, 1);
|
||||
event_info->listener = listener;
|
||||
event_info->func_data = data;
|
||||
|
||||
g_hash_table_insert (key_listener_list, GUINT_TO_POINTER (key++), event_info);
|
||||
/* XXX: we don't check to see if n_listeners > MAXUINT */
|
||||
return key - 1;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_accessibility_remove_key_event_listener (guint remove_listener)
|
||||
{
|
||||
if (!g_hash_table_remove (key_listener_list, GUINT_TO_POINTER (remove_listener))) {
|
||||
g_warning ("Not able to remove listener with id %i", remove_listener);
|
||||
}
|
||||
|
||||
if (g_hash_table_size (key_listener_list) == 0)
|
||||
{
|
||||
g_hash_table_destroy (key_listener_list);
|
||||
key_listener_list = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------ PRIVATE FUNCTIONS ------------------------- */
|
||||
|
||||
static AtkKeyEventStruct *
|
||||
atk_key_event_from_clutter_event_key (ClutterKeyEvent *clutter_event,
|
||||
gunichar password_char)
|
||||
{
|
||||
AtkKeyEventStruct *atk_event = g_new0 (AtkKeyEventStruct, 1);
|
||||
gunichar key_unichar;
|
||||
|
||||
switch (clutter_event_type ((ClutterEvent *) clutter_event))
|
||||
{
|
||||
case CLUTTER_KEY_PRESS:
|
||||
atk_event->type = ATK_KEY_EVENT_PRESS;
|
||||
break;
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
atk_event->type = ATK_KEY_EVENT_RELEASE;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (password_char)
|
||||
atk_event->state = 0;
|
||||
else
|
||||
atk_event->state = clutter_event_get_state ((ClutterEvent *) clutter_event);
|
||||
|
||||
/* We emit the clutter keyval. This is not exactly the one expected
|
||||
by AtkKeyEventStruct, as it expects a Gdk-like event, with the
|
||||
modifiers applied. But to avoid a dependency to gdk, we delegate
|
||||
that on the AT application.
|
||||
More information: Bug 1952 and bug 2072
|
||||
*/
|
||||
if (password_char)
|
||||
atk_event->keyval = clutter_unicode_to_keysym (password_char);
|
||||
else
|
||||
atk_event->keyval = clutter_event_get_key_symbol ((ClutterEvent *) clutter_event);
|
||||
|
||||
/* It is expected to store a key defining string here (ie "Space" in
|
||||
case you press a space). Anyway, there are no function on clutter
|
||||
to obtain that, and we want to avoid a gdk dependency here, so we
|
||||
delegate on the AT application to obtain that string using the
|
||||
rest of the data on the ATK event struct.
|
||||
|
||||
More information: Bug 1952 and 2072
|
||||
*/
|
||||
|
||||
if (password_char)
|
||||
key_unichar = password_char;
|
||||
else
|
||||
key_unichar = clutter_event_get_key_unicode ((ClutterEvent *) clutter_event);
|
||||
|
||||
if (g_unichar_validate (key_unichar) && !g_unichar_iscntrl (key_unichar))
|
||||
{
|
||||
GString *new = NULL;
|
||||
|
||||
new = g_string_new ("");
|
||||
new = g_string_insert_unichar (new, 0, key_unichar);
|
||||
atk_event->string = g_string_free (new, FALSE);
|
||||
}
|
||||
else
|
||||
atk_event->string = NULL;
|
||||
|
||||
atk_event->length = 0;
|
||||
|
||||
/* Computing the hardware keycode from the password-char is
|
||||
difficult. But we are in a password situation. We are already a
|
||||
unichar that it is not the original one. Providing a "almost
|
||||
real" keycode is irrelevant */
|
||||
if (password_char)
|
||||
atk_event->keycode = 0;
|
||||
else
|
||||
atk_event->keycode = clutter_event_get_key_code ((ClutterEvent *) clutter_event);
|
||||
|
||||
atk_event->timestamp = clutter_event_get_time ((ClutterEvent *) clutter_event);
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
|
||||
g_debug ("KeyEvent:\tsym 0x%x\n\t\tmods %x\n\t\tcode %u\n\t\ttime %lx \n\t\tstring %s\n",
|
||||
(unsigned int) atk_event->keyval,
|
||||
(unsigned int) atk_event->state,
|
||||
(unsigned int) atk_event->keycode,
|
||||
(unsigned long int) atk_event->timestamp,
|
||||
atk_event->string);
|
||||
#endif
|
||||
|
||||
return atk_event;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
notify_hf (gpointer key,
|
||||
gpointer value,
|
||||
gpointer data)
|
||||
{
|
||||
KeyEventInfo *info = (KeyEventInfo *) value;
|
||||
AtkKeyEventStruct *key_event = (AtkKeyEventStruct *)data;
|
||||
|
||||
return (*(AtkKeySnoopFunc) info->listener) (key_event, info->func_data) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
insert_hf (gpointer key,
|
||||
gpointer value,
|
||||
gpointer data)
|
||||
{
|
||||
GHashTable *new_table = (GHashTable *) data;
|
||||
g_hash_table_insert (new_table, key, value);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 0 if the key of that event is visible, in other case the password
|
||||
* char
|
||||
*/
|
||||
static gunichar
|
||||
check_key_visibility (ClutterStage *stage)
|
||||
{
|
||||
AtkObject *accessible;
|
||||
ClutterActor *focus;
|
||||
|
||||
focus = clutter_stage_get_key_focus (stage);
|
||||
if (focus == NULL)
|
||||
focus = CLUTTER_ACTOR (stage);
|
||||
accessible = clutter_actor_get_accessible (focus);
|
||||
|
||||
g_return_val_if_fail (accessible != NULL, 0);
|
||||
|
||||
if (atk_object_get_role (accessible) != ATK_ROLE_PASSWORD_TEXT)
|
||||
return 0;
|
||||
|
||||
/* If it is a clutter text, we use his password char. Note that
|
||||
although at Clutter toolkit itself, only ClutterText exposes a
|
||||
password role, nothing prevents on any derived toolkit (like st)
|
||||
to create a new actor that can behave like a password entry. And
|
||||
the key event will still be emitted here. Although in that case
|
||||
we would lose any password char from the derived toolkit, it is
|
||||
still better fill this with a default unichar that the original
|
||||
one */
|
||||
|
||||
#ifdef HAVE_FONTS
|
||||
if (CLUTTER_IS_TEXT (focus))
|
||||
return clutter_text_get_password_char (CLUTTER_TEXT (focus));
|
||||
else
|
||||
#endif
|
||||
return DEFAULT_PASSWORD_CHAR;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_accessibility_snoop_key_event (ClutterStage *stage,
|
||||
ClutterKeyEvent *key)
|
||||
{
|
||||
ClutterEvent *event = (ClutterEvent *) key;
|
||||
AtkKeyEventStruct *key_event = NULL;
|
||||
ClutterEventType event_type;
|
||||
gboolean consumed = FALSE;
|
||||
gunichar password_char = 0;
|
||||
|
||||
event_type = clutter_event_type (event);
|
||||
|
||||
/* filter key events */
|
||||
if ((event_type != CLUTTER_KEY_PRESS) && (event_type != CLUTTER_KEY_RELEASE))
|
||||
return FALSE;
|
||||
|
||||
if (key_listener_list)
|
||||
{
|
||||
GHashTable *new_hash = g_hash_table_new (NULL, NULL);
|
||||
|
||||
g_hash_table_foreach (key_listener_list, insert_hf, new_hash);
|
||||
password_char = check_key_visibility (stage);
|
||||
key_event = atk_key_event_from_clutter_event_key (key, password_char);
|
||||
/* func data is inside the hash table */
|
||||
consumed = g_hash_table_foreach_steal (new_hash, notify_hf, key_event) > 0;
|
||||
g_hash_table_destroy (new_hash);
|
||||
|
||||
g_free (key_event->string);
|
||||
g_free (key_event);
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_accessibility_override_atk_util (void)
|
||||
{
|
||||
AtkUtilClass *atk_class = ATK_UTIL_CLASS (g_type_class_ref (ATK_TYPE_UTIL));
|
||||
|
||||
if (atk_class->get_root)
|
||||
return;
|
||||
|
||||
atk_class->add_key_event_listener = clutter_accessibility_add_key_event_listener;
|
||||
atk_class->remove_key_event_listener = clutter_accessibility_remove_key_event_listener;
|
||||
atk_class->get_root = clutter_accessibility_get_root;
|
||||
atk_class->get_toolkit_name = clutter_accessibility_get_toolkit_name;
|
||||
atk_class->get_toolkit_version = clutter_accessibility_get_toolkit_version;
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2021 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-action.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void clutter_action_set_phase (ClutterAction *action,
|
||||
ClutterEventPhase phase);
|
||||
|
||||
gboolean clutter_action_handle_event (ClutterAction *action,
|
||||
const ClutterEvent *event);
|
||||
|
||||
void clutter_action_sequence_cancelled (ClutterAction *action,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence);
|
||||
|
||||
gboolean clutter_action_register_sequence (ClutterAction *self,
|
||||
const ClutterEvent *event);
|
||||
|
||||
int clutter_action_setup_sequence_relationship (ClutterAction *action_1,
|
||||
ClutterAction *action_2,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -23,125 +23,39 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterAction:
|
||||
*
|
||||
* Abstract class for event-related logic
|
||||
* SECTION:clutter-action
|
||||
* @Title: ClutterAction
|
||||
* @Short_Description: Abstract class for event-related logic
|
||||
* @See_Also: #ClutterConstraint
|
||||
*
|
||||
* #ClutterAction is an abstract base class for event-related actions that
|
||||
* modify the user interaction of a [class@Actor], just like
|
||||
* [class@Constraint] is an abstract class for modifiers of an actor's
|
||||
* modify the user interaction of a #ClutterActor, just like
|
||||
* #ClutterConstraint is an abstract class for modifiers of an actor's
|
||||
* position or size.
|
||||
*
|
||||
* Implementations of #ClutterAction are associated to an actor and can
|
||||
* provide behavioral changes when dealing with user input - for instance
|
||||
* drag and drop capabilities, or scrolling, or panning - by using the
|
||||
* various event-related signals provided by [class@Actor] itself.
|
||||
* various event-related signals provided by #ClutterActor itself.
|
||||
*
|
||||
* #ClutterAction is available since Clutter 1.4
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter/clutter-action.h"
|
||||
#include "clutter/clutter-action-private.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#include "clutter-action.h"
|
||||
|
||||
typedef struct _ClutterActionPrivate ClutterActionPrivate;
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
struct _ClutterActionPrivate
|
||||
{
|
||||
ClutterEventPhase phase;
|
||||
};
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterAction, clutter_action,
|
||||
CLUTTER_TYPE_ACTOR_META)
|
||||
|
||||
static gboolean
|
||||
clutter_action_handle_event_default (ClutterAction *action,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
G_DEFINE_ABSTRACT_TYPE (ClutterAction, clutter_action, CLUTTER_TYPE_ACTOR_META);
|
||||
|
||||
static void
|
||||
clutter_action_class_init (ClutterActionClass *klass)
|
||||
{
|
||||
klass->handle_event = clutter_action_handle_event_default;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_action_init (ClutterAction *self)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
clutter_action_set_phase (ClutterAction *action,
|
||||
ClutterEventPhase phase)
|
||||
{
|
||||
ClutterActionPrivate *priv;
|
||||
|
||||
priv = clutter_action_get_instance_private (action);
|
||||
priv->phase = phase;
|
||||
}
|
||||
|
||||
ClutterEventPhase
|
||||
clutter_action_get_phase (ClutterAction *action)
|
||||
{
|
||||
ClutterActionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTION (action), CLUTTER_PHASE_CAPTURE);
|
||||
|
||||
priv = clutter_action_get_instance_private (action);
|
||||
|
||||
return priv->phase;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_action_handle_event (ClutterAction *action,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
gboolean retval = CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
g_object_ref (action);
|
||||
if (clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)))
|
||||
retval = CLUTTER_ACTION_GET_CLASS (action)->handle_event (action, event);
|
||||
g_object_unref (action);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_action_sequence_cancelled (ClutterAction *action,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence)
|
||||
{
|
||||
ClutterActionClass *action_class = CLUTTER_ACTION_GET_CLASS (action);
|
||||
|
||||
if (action_class->sequence_cancelled)
|
||||
action_class->sequence_cancelled (action, device, sequence);
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_action_register_sequence (ClutterAction *self,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
ClutterActionClass *action_class = CLUTTER_ACTION_GET_CLASS (self);
|
||||
|
||||
if (action_class->register_sequence)
|
||||
return action_class->register_sequence (self, event);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
clutter_action_setup_sequence_relationship (ClutterAction *action_1,
|
||||
ClutterAction *action_2,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence)
|
||||
{
|
||||
ClutterActionClass *action_class = CLUTTER_ACTION_GET_CLASS (action_1);
|
||||
|
||||
if (action_class->setup_sequence_relationship)
|
||||
return action_class->setup_sequence_relationship (action_1, action_2, device, sequence);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -22,48 +22,65 @@
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_ACTION_H__
|
||||
#define __CLUTTER_ACTION_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-actor-meta.h"
|
||||
#include <clutter/clutter-actor-meta.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_ACTION (clutter_action_get_type ())
|
||||
#define CLUTTER_TYPE_ACTION (clutter_action_get_type ())
|
||||
#define CLUTTER_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTION, ClutterAction))
|
||||
#define CLUTTER_IS_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTION))
|
||||
#define CLUTTER_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTION, ClutterActionClass))
|
||||
#define CLUTTER_IS_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTION))
|
||||
#define CLUTTER_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTION, ClutterActionClass))
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterAction, clutter_action,
|
||||
CLUTTER, ACTION, ClutterActorMeta);
|
||||
typedef struct _ClutterActionClass ClutterActionClass;
|
||||
|
||||
/**
|
||||
* ClutterAction:
|
||||
*
|
||||
* The #ClutterAction structure contains only private data and
|
||||
* should be accessed using the provided API.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _ClutterAction
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterActorMeta parent_instance;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterActionClass:
|
||||
*
|
||||
* The ClutterActionClass structure contains only private data
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _ClutterActionClass
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterActorMetaClass parent_class;
|
||||
|
||||
gboolean (* handle_event) (ClutterAction *action,
|
||||
const ClutterEvent *event);
|
||||
|
||||
void (* sequence_cancelled) (ClutterAction *action,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence);
|
||||
|
||||
gboolean (* register_sequence) (ClutterAction *self,
|
||||
const ClutterEvent *event);
|
||||
|
||||
int (* setup_sequence_relationship) (ClutterAction *action_1,
|
||||
ClutterAction *action_2,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence);
|
||||
void (* _clutter_action1) (void);
|
||||
void (* _clutter_action2) (void);
|
||||
void (* _clutter_action3) (void);
|
||||
void (* _clutter_action4) (void);
|
||||
void (* _clutter_action5) (void);
|
||||
void (* _clutter_action6) (void);
|
||||
void (* _clutter_action7) (void);
|
||||
void (* _clutter_action8) (void);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_action_get_type (void) G_GNUC_CONST;
|
||||
|
||||
/* ClutterActor API */
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_add_action (ClutterActor *self,
|
||||
@@ -73,11 +90,6 @@ void clutter_actor_add_action_with_name (ClutterActor *self,
|
||||
const gchar *name,
|
||||
ClutterAction *action);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_add_action_full (ClutterActor *self,
|
||||
const char *name,
|
||||
ClutterEventPhase phase,
|
||||
ClutterAction *action);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_remove_action (ClutterActor *self,
|
||||
ClutterAction *action);
|
||||
CLUTTER_EXPORT
|
||||
@@ -94,6 +106,6 @@ void clutter_actor_clear_actions (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_has_actions (ClutterActor *self);
|
||||
|
||||
ClutterEventPhase clutter_action_get_phase (ClutterAction *action);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ACTION_H__ */
|
||||
|
||||
@@ -1,549 +0,0 @@
|
||||
/* Clutter.
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* Some parts are based on GailWidget from GAIL
|
||||
* GAIL - The GNOME Accessibility Implementation Library
|
||||
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterActorAccessible:
|
||||
*
|
||||
* Implementation of the ATK interfaces for [class@Clutter.Actor]
|
||||
*
|
||||
* #ClutterActorAccessible implements the required ATK interfaces of [class@Clutter.Actor]
|
||||
* exposing the common elements on each actor (position, extents, etc).
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* IMPLEMENTATION NOTES:
|
||||
*
|
||||
* ####
|
||||
*
|
||||
* Focus: clutter hasn't got the focus concept in the same way that GTK, but it
|
||||
* has a key focus managed by the stage. Basically any actor can be focused using
|
||||
* clutter_stage_set_key_focus. So, we will use this approach: all actors are
|
||||
* focusable, and we get the currently focused using clutter_stage_get_key_focus
|
||||
* This affects focus related stateset and some atk_component focus methods (like
|
||||
* grab focus).
|
||||
*
|
||||
* In the same way, we will manage the focus state change management
|
||||
* on the cally-stage object. The reason is avoid missing a focus
|
||||
* state change event if the object is focused just before the
|
||||
* accessibility object being created.
|
||||
*
|
||||
* #AtkAction implementation: on previous releases ClutterActor added
|
||||
* the actions "press", "release" and "click", as at that time some
|
||||
* general-purpose actors like textures were directly used as buttons.
|
||||
*
|
||||
* But now, new toolkits appeared, providing high-level widgets, like
|
||||
* buttons. So in this environment, it doesn't make sense to keep
|
||||
* adding them as default.
|
||||
*
|
||||
* Anyway, current implementation of AtkAction is done at ClutterActorAccessible
|
||||
* providing methods to add and remove actions. This is based on the
|
||||
* one used at gailcell, and proposed as a change on #AtkAction
|
||||
* interface:
|
||||
*
|
||||
* https://bugzilla.gnome.org/show_bug.cgi?id=649804
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <atk/atk.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "clutter/clutter-actor-private.h"
|
||||
#include "clutter/clutter-actor-accessible.h"
|
||||
#include "clutter/clutter-stage.h"
|
||||
|
||||
/* AtkComponent.h */
|
||||
static void clutter_actor_accessible_component_interface_init (AtkComponentIface *iface);
|
||||
|
||||
struct _ClutterActorAccessiblePrivate
|
||||
{
|
||||
GList *children;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (ClutterActorAccessible,
|
||||
clutter_actor_accessible,
|
||||
ATK_TYPE_GOBJECT_ACCESSIBLE,
|
||||
G_ADD_PRIVATE (ClutterActorAccessible)
|
||||
G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT,
|
||||
clutter_actor_accessible_component_interface_init));
|
||||
|
||||
/* ClutterContainer */
|
||||
static gint
|
||||
clutter_actor_accessible_add_actor (ClutterActor *container,
|
||||
ClutterActor *actor,
|
||||
gpointer data)
|
||||
{
|
||||
AtkObject *atk_parent = clutter_actor_get_accessible (container);
|
||||
AtkObject *atk_child = clutter_actor_get_accessible (actor);
|
||||
ClutterActorAccessiblePrivate *priv = clutter_actor_accessible_get_instance_private (CLUTTER_ACTOR_ACCESSIBLE (atk_parent));
|
||||
gint index;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (container), 0);
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0);
|
||||
|
||||
g_object_notify (G_OBJECT (atk_child), "accessible_parent");
|
||||
|
||||
g_list_free (priv->children);
|
||||
|
||||
priv->children = clutter_actor_get_children (CLUTTER_ACTOR (container));
|
||||
|
||||
index = g_list_index (priv->children, actor);
|
||||
g_signal_emit_by_name (atk_parent, "children_changed::add",
|
||||
index, atk_child, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static gint
|
||||
clutter_actor_accessible_remove_actor (ClutterActor *container,
|
||||
ClutterActor *actor,
|
||||
gpointer data)
|
||||
{
|
||||
g_autoptr (AtkObject) atk_child = NULL;
|
||||
AtkPropertyValues values = { NULL };
|
||||
AtkObject *atk_parent = NULL;
|
||||
ClutterActorAccessiblePrivate *priv = NULL;
|
||||
gint index;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (container), 0);
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0);
|
||||
|
||||
atk_parent = clutter_actor_get_accessible (container);
|
||||
atk_child = clutter_actor_get_accessible (actor);
|
||||
|
||||
if (atk_child)
|
||||
{
|
||||
g_assert (ATK_IS_OBJECT (atk_child));
|
||||
g_object_ref (atk_child);
|
||||
|
||||
g_value_init (&values.old_value, G_TYPE_POINTER);
|
||||
g_value_set_pointer (&values.old_value, atk_parent);
|
||||
|
||||
values.property_name = "accessible-parent";
|
||||
|
||||
g_signal_emit_by_name (atk_child,
|
||||
"property_change::accessible-parent", &values, NULL);
|
||||
}
|
||||
|
||||
priv = clutter_actor_accessible_get_instance_private (CLUTTER_ACTOR_ACCESSIBLE (atk_parent));
|
||||
index = g_list_index (priv->children, actor);
|
||||
g_list_free (priv->children);
|
||||
|
||||
priv->children = clutter_actor_get_children (CLUTTER_ACTOR (container));
|
||||
|
||||
if (index >= 0 && index <= g_list_length (priv->children))
|
||||
g_signal_emit_by_name (atk_parent, "children_changed::remove",
|
||||
index, atk_child, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_accessible_initialize (AtkObject *obj,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterActorAccessible *self = NULL;
|
||||
ClutterActorAccessiblePrivate *priv = NULL;
|
||||
ClutterActor *actor = NULL;
|
||||
guint handler_id;
|
||||
|
||||
ATK_OBJECT_CLASS (clutter_actor_accessible_parent_class)->initialize (obj, data);
|
||||
|
||||
self = CLUTTER_ACTOR_ACCESSIBLE (obj);
|
||||
priv = clutter_actor_accessible_get_instance_private (self);
|
||||
actor = CLUTTER_ACTOR (data);
|
||||
|
||||
g_object_set_data (G_OBJECT (obj), "atk-component-layer",
|
||||
GINT_TO_POINTER (ATK_LAYER_MDI));
|
||||
|
||||
priv->children = clutter_actor_get_children (actor);
|
||||
|
||||
/*
|
||||
* We store the handler ids for these signals in case some objects
|
||||
* need to remove these handlers.
|
||||
*/
|
||||
handler_id = g_signal_connect (actor,
|
||||
"child-added",
|
||||
G_CALLBACK (clutter_actor_accessible_add_actor),
|
||||
obj);
|
||||
g_object_set_data (G_OBJECT (obj), "cally-add-handler-id",
|
||||
GUINT_TO_POINTER (handler_id));
|
||||
handler_id = g_signal_connect (actor,
|
||||
"child-removed",
|
||||
G_CALLBACK (clutter_actor_accessible_remove_actor),
|
||||
obj);
|
||||
g_object_set_data (G_OBJECT (obj), "cally-remove-handler-id",
|
||||
GUINT_TO_POINTER (handler_id));
|
||||
|
||||
obj->role = ATK_ROLE_PANEL; /* typically objects implementing ClutterContainer
|
||||
interface would be a panel */
|
||||
}
|
||||
|
||||
/* AtkObject */
|
||||
static const gchar *
|
||||
clutter_actor_accessible_get_name (AtkObject *obj)
|
||||
{
|
||||
const gchar* name = NULL;
|
||||
ClutterActor *actor;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (obj), NULL);
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (obj);
|
||||
if (actor)
|
||||
name = clutter_actor_get_accessible_name (actor);
|
||||
|
||||
if (!name)
|
||||
name = ATK_OBJECT_CLASS (clutter_actor_accessible_parent_class)->get_name (obj);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static AtkRole
|
||||
clutter_actor_accessible_get_role (AtkObject *obj)
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
AtkRole role = ATK_ROLE_INVALID;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (obj), role);
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (obj);
|
||||
|
||||
if (actor == NULL)
|
||||
return role;
|
||||
|
||||
role = actor->accessible_role;
|
||||
if (role == ATK_ROLE_INVALID)
|
||||
role = ATK_OBJECT_CLASS (clutter_actor_accessible_parent_class)->get_role (obj);
|
||||
|
||||
return role;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_accessible_init (ClutterActorAccessible *actor_accessible)
|
||||
{
|
||||
ClutterActorAccessiblePrivate *priv = clutter_actor_accessible_get_instance_private (actor_accessible);
|
||||
priv->children = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_accessible_finalize (GObject *obj)
|
||||
{
|
||||
ClutterActorAccessible *actor_accessible =
|
||||
CLUTTER_ACTOR_ACCESSIBLE (obj);
|
||||
ClutterActorAccessiblePrivate *priv =
|
||||
clutter_actor_accessible_get_instance_private (actor_accessible);
|
||||
|
||||
if (priv->children)
|
||||
{
|
||||
g_list_free (priv->children);
|
||||
priv->children = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (clutter_actor_accessible_parent_class)->finalize (obj);
|
||||
}
|
||||
|
||||
static AtkObject *
|
||||
clutter_actor_accessible_get_parent (AtkObject *obj)
|
||||
{
|
||||
ClutterActor *parent_actor = NULL;
|
||||
AtkObject *parent = NULL;
|
||||
ClutterActor *actor = NULL;
|
||||
ClutterActorAccessible *actor_accessible = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (obj), NULL);
|
||||
|
||||
/* Check if we have and assigned parent */
|
||||
if (obj->accessible_parent)
|
||||
return obj->accessible_parent;
|
||||
|
||||
/* Try to get it from the clutter parent */
|
||||
actor_accessible = CLUTTER_ACTOR_ACCESSIBLE (obj);
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (actor_accessible);
|
||||
if (actor == NULL) /* Object is defunct */
|
||||
return NULL;
|
||||
|
||||
parent_actor = clutter_actor_get_parent (actor);
|
||||
if (parent_actor == NULL)
|
||||
return NULL;
|
||||
|
||||
parent = clutter_actor_get_accessible (parent_actor);
|
||||
|
||||
/* FIXME: I need to review the clutter-embed, to check if in this case I
|
||||
* should get the widget accessible
|
||||
*/
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
static gint
|
||||
clutter_actor_accessible_get_index_in_parent (AtkObject *obj)
|
||||
{
|
||||
ClutterActorAccessible *actor_accessible = NULL;
|
||||
ClutterActor *actor = NULL;
|
||||
ClutterActor *parent_actor = NULL;
|
||||
ClutterActor *iter;
|
||||
gint index = -1;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (obj), -1);
|
||||
|
||||
if (obj->accessible_parent)
|
||||
{
|
||||
gint n_children, i;
|
||||
gboolean found = FALSE;
|
||||
|
||||
n_children = atk_object_get_n_accessible_children (obj->accessible_parent);
|
||||
for (i = 0; i < n_children; i++)
|
||||
{
|
||||
AtkObject *child;
|
||||
|
||||
child = atk_object_ref_accessible_child (obj->accessible_parent, i);
|
||||
if (child == obj)
|
||||
found = TRUE;
|
||||
|
||||
g_object_unref (child);
|
||||
if (found)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
actor_accessible = CLUTTER_ACTOR_ACCESSIBLE (obj);
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (actor_accessible);
|
||||
if (actor == NULL) /* Object is defunct */
|
||||
return -1;
|
||||
|
||||
index = 0;
|
||||
parent_actor = clutter_actor_get_parent (actor);
|
||||
if (parent_actor == NULL)
|
||||
return -1;
|
||||
|
||||
for (iter = clutter_actor_get_first_child (parent_actor);
|
||||
iter != NULL && iter != actor;
|
||||
iter = clutter_actor_get_next_sibling (iter))
|
||||
{
|
||||
index += 1;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static AtkStateSet*
|
||||
clutter_actor_accessible_ref_state_set (AtkObject *obj)
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
g_autoptr (AtkStateSet) parent_state = NULL;
|
||||
AtkStateSet *combined_state, *actor_state = NULL;
|
||||
ClutterActorAccessible *actor_accessible = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (obj), NULL);
|
||||
actor_accessible = CLUTTER_ACTOR_ACCESSIBLE (obj);
|
||||
|
||||
parent_state = ATK_OBJECT_CLASS (clutter_actor_accessible_parent_class)->ref_state_set (obj);
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (actor_accessible);
|
||||
|
||||
if (actor == NULL) /* Object is defunct */
|
||||
{
|
||||
atk_state_set_add_state (parent_state, ATK_STATE_DEFUNCT);
|
||||
combined_state = g_steal_pointer (&parent_state);
|
||||
}
|
||||
else
|
||||
{
|
||||
actor_state = clutter_actor_get_accessible_state (actor);
|
||||
|
||||
if (actor_state)
|
||||
combined_state = atk_state_set_or_sets (parent_state,
|
||||
actor_state);
|
||||
else
|
||||
combined_state = g_steal_pointer (&parent_state);
|
||||
}
|
||||
|
||||
return combined_state;
|
||||
}
|
||||
|
||||
static gint
|
||||
clutter_actor_accessible_get_n_children (AtkObject *obj)
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (obj), 0);
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (obj);
|
||||
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return 0;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0);
|
||||
|
||||
return clutter_actor_get_n_children (actor);
|
||||
}
|
||||
|
||||
static AtkObject*
|
||||
clutter_actor_accessible_ref_child (AtkObject *obj,
|
||||
gint i)
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
ClutterActor *child = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (obj), NULL);
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (obj);
|
||||
if (actor == NULL) /* State is defunct */
|
||||
return NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL);
|
||||
|
||||
if (i >= clutter_actor_get_n_children (actor))
|
||||
return NULL;
|
||||
|
||||
child = clutter_actor_get_child_at_index (actor, i);
|
||||
if (child == NULL)
|
||||
return NULL;
|
||||
|
||||
return g_object_ref (clutter_actor_get_accessible (child));
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_accessible_class_init (ClutterActorAccessibleClass *klass)
|
||||
{
|
||||
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
/* GObject */
|
||||
gobject_class->finalize = clutter_actor_accessible_finalize;
|
||||
|
||||
/* AtkObject */
|
||||
class->get_role = clutter_actor_accessible_get_role;
|
||||
class->get_name = clutter_actor_accessible_get_name;
|
||||
class->get_parent = clutter_actor_accessible_get_parent;
|
||||
class->get_index_in_parent = clutter_actor_accessible_get_index_in_parent;
|
||||
class->ref_state_set = clutter_actor_accessible_ref_state_set;
|
||||
class->initialize = clutter_actor_accessible_initialize;
|
||||
class->get_n_children = clutter_actor_accessible_get_n_children;
|
||||
class->ref_child = clutter_actor_accessible_ref_child;
|
||||
}
|
||||
|
||||
/* AtkComponent implementation */
|
||||
static void
|
||||
clutter_actor_accessible_get_extents (AtkComponent *component,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gint *width,
|
||||
gint *height,
|
||||
AtkCoordType coord_type)
|
||||
{
|
||||
ClutterActorAccessible *actor_accessible = NULL;
|
||||
ClutterActor *actor = NULL;
|
||||
gfloat f_width, f_height;
|
||||
graphene_point3d_t verts[4];
|
||||
ClutterActor *stage = NULL;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (component));
|
||||
|
||||
actor_accessible = CLUTTER_ACTOR_ACCESSIBLE (component);
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (actor_accessible);
|
||||
|
||||
if (actor == NULL) /* actor is defunct */
|
||||
return;
|
||||
|
||||
/* If the actor is not placed in any stage, we can't compute the
|
||||
* extents */
|
||||
stage = clutter_actor_get_stage (actor);
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
clutter_actor_get_abs_allocation_vertices (actor, verts);
|
||||
clutter_actor_get_transformed_size (actor, &f_width, &f_height);
|
||||
|
||||
*x = (int) verts[0].x;
|
||||
*y = (int) verts[0].y;
|
||||
*width = (int) ceilf (f_width);
|
||||
*height = (int) ceilf (f_height);
|
||||
}
|
||||
|
||||
static gint
|
||||
clutter_actor_accessible_get_mdi_zorder (AtkComponent *component)
|
||||
{
|
||||
ClutterActorAccessible *actor_accessible = NULL;
|
||||
ClutterActor *actor = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (component), G_MININT);
|
||||
|
||||
actor_accessible = CLUTTER_ACTOR_ACCESSIBLE (component);
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (actor_accessible);
|
||||
|
||||
return (int) clutter_actor_get_z_position (actor);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_actor_accessible_grab_focus (AtkComponent *component)
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
ClutterActor *stage = NULL;
|
||||
ClutterActorAccessible *actor_accessible = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (component), FALSE);
|
||||
|
||||
/* See focus section on implementation notes */
|
||||
actor_accessible = CLUTTER_ACTOR_ACCESSIBLE (component);
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (actor_accessible);
|
||||
stage = clutter_actor_get_stage (actor);
|
||||
|
||||
clutter_stage_set_key_focus (CLUTTER_STAGE (stage),
|
||||
actor);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static double
|
||||
clutter_actor_accessible_get_alpha (AtkComponent *component)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (component), 1.0);
|
||||
|
||||
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (component);
|
||||
|
||||
if (!actor)
|
||||
return 1.0;
|
||||
|
||||
return clutter_actor_get_opacity (actor) / 255.0;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_accessible_component_interface_init (AtkComponentIface *iface)
|
||||
{
|
||||
g_return_if_fail (iface != NULL);
|
||||
|
||||
iface->get_extents = clutter_actor_accessible_get_extents;
|
||||
iface->get_mdi_zorder = clutter_actor_accessible_get_mdi_zorder;
|
||||
iface->get_alpha = clutter_actor_accessible_get_alpha;
|
||||
|
||||
/* focus management */
|
||||
iface->grab_focus = clutter_actor_accessible_grab_focus;
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_ACTOR_BOX_PRIVATE_H__
|
||||
#define __CLUTTER_ACTOR_BOX_PRIVATE_H__
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
#include <clutter/clutter-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void _clutter_actor_box_enlarge_for_effects (ClutterActorBox *box);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ACTOR_BOX_PRIVATE_H__ */
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
#include "clutter/clutter-interval.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#include "clutter/clutter-actor-box-private.h"
|
||||
#include "clutter-types.h"
|
||||
#include "clutter-interval.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-actor-box-private.h"
|
||||
|
||||
/**
|
||||
* clutter_actor_box_new:
|
||||
@@ -14,19 +14,21 @@
|
||||
* @x_2: X coordinate of the bottom right point
|
||||
* @y_2: Y coordinate of the bottom right point
|
||||
*
|
||||
* Allocates a new [struct@ActorBox] using the passed coordinates
|
||||
* Allocates a new #ClutterActorBox using the passed coordinates
|
||||
* for the top left and bottom right points.
|
||||
*
|
||||
* This function is the logical equivalent of:
|
||||
*
|
||||
* ```c
|
||||
* |[
|
||||
* clutter_actor_box_init (clutter_actor_box_alloc (),
|
||||
* x_1, y_1,
|
||||
* x_2, y_2);
|
||||
* ```
|
||||
* ]|
|
||||
*
|
||||
* Return value: (transfer full): the newly allocated #ClutterActorBox.
|
||||
* Use [method@ActorBox.free] to free the resources
|
||||
* Use clutter_actor_box_free() to free the resources
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
ClutterActorBox *
|
||||
clutter_actor_box_new (gfloat x_1,
|
||||
@@ -42,15 +44,17 @@ clutter_actor_box_new (gfloat x_1,
|
||||
/**
|
||||
* clutter_actor_box_alloc:
|
||||
*
|
||||
* Allocates a new [struct@ActorBox].
|
||||
* Allocates a new #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 *
|
||||
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.
|
||||
*
|
||||
* Return value: (transfer none): the initialized #ClutterActorBox
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
ClutterActorBox *
|
||||
clutter_actor_box_init (ClutterActorBox *box,
|
||||
@@ -91,6 +97,8 @@ clutter_actor_box_init (ClutterActorBox *box,
|
||||
* @height: height of the box
|
||||
*
|
||||
* Initializes @box with the given origin and size.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_init_rect (ClutterActorBox *box,
|
||||
@@ -114,13 +122,15 @@ clutter_actor_box_init_rect (ClutterActorBox *box,
|
||||
* Copies @box
|
||||
*
|
||||
* 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 *
|
||||
clutter_actor_box_copy (const ClutterActorBox *box)
|
||||
{
|
||||
if (G_LIKELY (box != NULL))
|
||||
return g_memdup2 (box, sizeof (ClutterActorBox));
|
||||
return g_slice_dup (ClutterActorBox, box);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -129,14 +139,16 @@ clutter_actor_box_copy (const ClutterActorBox *box)
|
||||
* clutter_actor_box_free:
|
||||
* @box: a #ClutterActorBox
|
||||
*
|
||||
* Frees a #ClutterActorBox allocated using [ctor@ActorBox.new]
|
||||
* or [method@ActorBox.copy].
|
||||
* Frees a #ClutterActorBox allocated using clutter_actor_box_new()
|
||||
* or clutter_actor_box_copy()
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_free (ClutterActorBox *box)
|
||||
{
|
||||
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
|
||||
*
|
||||
* Return value: %TRUE if the passed #ClutterActorBox are equal
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
gboolean
|
||||
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
|
||||
*
|
||||
* Return value: the X coordinate of the origin
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
gfloat
|
||||
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
|
||||
*
|
||||
* Return value: the Y coordinate of the origin
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
gfloat
|
||||
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
|
||||
*
|
||||
* Return value: the width of the box
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
gfloat
|
||||
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
|
||||
*
|
||||
* Return value: the height of the box
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
gfloat
|
||||
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
|
||||
*
|
||||
* Retrieves the origin of @box
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
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
|
||||
*
|
||||
* Retrieves the size of @box
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
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
|
||||
*
|
||||
* Return value: the area of a #ClutterActorBox, in pixels
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
gfloat
|
||||
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
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
gboolean
|
||||
clutter_actor_box_contains (const ClutterActorBox *box,
|
||||
@@ -310,14 +340,16 @@ clutter_actor_box_contains (const ClutterActorBox *box,
|
||||
/**
|
||||
* clutter_actor_box_from_vertices:
|
||||
* @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
|
||||
* 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
|
||||
clutter_actor_box_from_vertices (ClutterActorBox *box,
|
||||
const graphene_point3d_t verts[])
|
||||
clutter_actor_box_from_vertices (ClutterActorBox *box,
|
||||
const ClutterVertex verts[])
|
||||
{
|
||||
gfloat x_1, x_2, y_1, y_2;
|
||||
|
||||
@@ -380,8 +412,10 @@ clutter_actor_box_from_vertices (ClutterActorBox *box,
|
||||
* @progress: the interpolation progress
|
||||
* @result: (out): return location for the interpolation
|
||||
*
|
||||
* Interpolates between @initial and @final `ClutterActorBox`es
|
||||
* Interpolates between @initial and @final #ClutterActorBox<!-- -->es
|
||||
* using @progress
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_interpolate (const ClutterActorBox *initial,
|
||||
@@ -393,10 +427,10 @@ clutter_actor_box_interpolate (const ClutterActorBox *initial,
|
||||
g_return_if_fail (final != NULL);
|
||||
g_return_if_fail (result != NULL);
|
||||
|
||||
result->x1 = (float) (initial->x1 + (final->x1 - initial->x1) * progress);
|
||||
result->y1 = (float) (initial->y1 + (final->y1 - initial->y1) * progress);
|
||||
result->x2 = (float) (initial->x2 + (final->x2 - initial->x2) * progress);
|
||||
result->y2 = (float) (initial->y2 + (final->y2 - initial->y2) * progress);
|
||||
result->x1 = initial->x1 + (final->x1 - initial->x1) * progress;
|
||||
result->y1 = initial->y1 + (final->y1 - initial->y1) * progress;
|
||||
result->x2 = initial->x2 + (final->x2 - initial->x2) * progress;
|
||||
result->y2 = initial->y2 + (final->y2 - initial->y2) * progress;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -404,6 +438,8 @@ clutter_actor_box_interpolate (const ClutterActorBox *initial,
|
||||
* @box: (inout): the #ClutterActorBox to clamp
|
||||
*
|
||||
* Clamps the components of @box to the nearest integer
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_clamp_to_pixel (ClutterActorBox *box)
|
||||
@@ -424,6 +460,8 @@ clutter_actor_box_clamp_to_pixel (ClutterActorBox *box)
|
||||
* of @a and @b
|
||||
*
|
||||
* Unions the two boxes @a and @b and stores the result in @result.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
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
|
||||
*
|
||||
* Changes the origin of @box, maintaining the size of the #ClutterActorBox.
|
||||
*
|
||||
* Since: 1.6
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_set_origin (ClutterActorBox *box,
|
||||
@@ -489,6 +529,8 @@ clutter_actor_box_set_origin (ClutterActorBox *box,
|
||||
* @height: the new height
|
||||
*
|
||||
* Sets the size of @box, maintaining the origin of the #ClutterActorBox.
|
||||
*
|
||||
* Since: 1.6
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_set_size (ClutterActorBox *box,
|
||||
@@ -506,16 +548,13 @@ _clutter_actor_box_enlarge_for_effects (ClutterActorBox *box)
|
||||
{
|
||||
float width, height;
|
||||
|
||||
if (clutter_actor_box_get_area (box) == 0.0)
|
||||
return;
|
||||
|
||||
/* The aim here is that for a given rectangle defined with floating point
|
||||
* coordinates we want to determine a stable quantized size in pixels
|
||||
* that doesn't vary due to the original box's sub-pixel position.
|
||||
*
|
||||
* The reason this is important is because effects will use this
|
||||
* API to determine the size of offscreen framebuffers and so for
|
||||
* a fixed-size object that may be animated across the screen we
|
||||
* a fixed-size object that may be animated accross the screen we
|
||||
* want to make sure that the stage paint-box has an equally stable
|
||||
* size so that effects aren't made to continuously re-allocate
|
||||
* a corresponding fbo.
|
||||
@@ -539,12 +578,12 @@ _clutter_actor_box_enlarge_for_effects (ClutterActorBox *box)
|
||||
* here is 1.75px in total if you consider that the 0.75 padding could
|
||||
* just cross an integer boundary and so ceil will effectively add 1.
|
||||
*/
|
||||
box->x2 = ceilf (box->x2 + 0.75f);
|
||||
box->y2 = ceilf (box->y2 + 0.75f);
|
||||
box->x2 = ceilf (box->x2 + 0.75);
|
||||
box->y2 = ceilf (box->y2 + 0.75);
|
||||
|
||||
/* Now we redefine the top-left relative to the bottom right based on the
|
||||
* rounded width/height determined above + a constant so that the overall
|
||||
* size of the box will be stable and not dependent on the box's
|
||||
* size of the box will be stable and not dependant on the box's
|
||||
* position.
|
||||
*
|
||||
* Adding 3px to the width/height will ensure we cover the maximum of
|
||||
@@ -561,6 +600,8 @@ _clutter_actor_box_enlarge_for_effects (ClutterActorBox *box)
|
||||
* @scale: scale factor for resizing this box
|
||||
*
|
||||
* Rescale the @box by provided @scale factor.
|
||||
*
|
||||
* Since: 1.6
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_scale (ClutterActorBox *box,
|
||||
@@ -574,32 +615,6 @@ clutter_actor_box_scale (ClutterActorBox *box,
|
||||
box->y2 *= scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_is_initialized:
|
||||
* @box: a #ClutterActorBox
|
||||
*
|
||||
* Checks if @box has been initialized, a #ClutterActorBox is uninitialized
|
||||
* if it has a size of -1 at an origin of 0, 0.
|
||||
*
|
||||
* Returns: %TRUE if the box is uninitialized, %FALSE if it isn't
|
||||
*/
|
||||
gboolean
|
||||
clutter_actor_box_is_initialized (ClutterActorBox *box)
|
||||
{
|
||||
gboolean x1_uninitialized, x2_uninitialized;
|
||||
gboolean y1_uninitialized, y2_uninitialized;
|
||||
|
||||
g_return_val_if_fail (box != NULL, TRUE);
|
||||
|
||||
x1_uninitialized = isinf (box->x1);
|
||||
x2_uninitialized = isinf (box->x2) && signbit (box->x2);
|
||||
y1_uninitialized = isinf (box->y1);
|
||||
y2_uninitialized = isinf (box->y2) && signbit (box->y2);
|
||||
|
||||
return !x1_uninitialized || !x2_uninitialized ||
|
||||
!y1_uninitialized || !y2_uninitialized;
|
||||
}
|
||||
|
||||
G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterActorBox, clutter_actor_box,
|
||||
clutter_actor_box_copy,
|
||||
clutter_actor_box_free,
|
||||
|
||||
@@ -22,14 +22,19 @@
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_ACTOR_META_PRIVATE_H__
|
||||
#define __CLUTTER_ACTOR_META_PRIVATE_H__
|
||||
|
||||
#include "clutter/clutter-actor-meta.h"
|
||||
#include <clutter/clutter-actor-meta.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_META_GROUP (_clutter_meta_group_get_type ())
|
||||
#define CLUTTER_META_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_META_GROUP, ClutterMetaGroup))
|
||||
#define CLUTTER_IS_META_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_META_GROUP))
|
||||
|
||||
typedef struct _ClutterMetaGroup ClutterMetaGroup;
|
||||
typedef struct _ClutterMetaGroupClass ClutterMetaGroupClass;
|
||||
|
||||
struct _ClutterMetaGroup
|
||||
{
|
||||
@@ -40,10 +45,10 @@ struct _ClutterMetaGroup
|
||||
GList *meta;
|
||||
};
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ClutterMetaGroup,
|
||||
_clutter_meta_group,
|
||||
CLUTTER, META_GROUP,
|
||||
GObject)
|
||||
struct _ClutterMetaGroupClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
/* Each actor meta has a priority with zero as a default. A higher
|
||||
number means higher priority. Higher priority metas stay at the
|
||||
@@ -59,6 +64,8 @@ G_DECLARE_FINAL_TYPE (ClutterMetaGroup,
|
||||
#define CLUTTER_ACTOR_META_PRIORITY_INTERNAL_HIGH (G_MAXINT / 2)
|
||||
#define CLUTTER_ACTOR_META_PRIORITY_INTERNAL_LOW (G_MININT / 2)
|
||||
|
||||
GType _clutter_meta_group_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void _clutter_meta_group_add_meta (ClutterMetaGroup *group,
|
||||
ClutterActorMeta *meta);
|
||||
void _clutter_meta_group_remove_meta (ClutterMetaGroup *group,
|
||||
@@ -74,9 +81,17 @@ GList * _clutter_meta_group_get_metas_no_internal (ClutterMeta
|
||||
void _clutter_meta_group_clear_metas_no_internal (ClutterMetaGroup *group);
|
||||
|
||||
/* ActorMeta */
|
||||
void _clutter_actor_meta_set_actor (ClutterActorMeta *meta,
|
||||
ClutterActor *actor);
|
||||
|
||||
const gchar * _clutter_actor_meta_get_debug_name (ClutterActorMeta *meta);
|
||||
|
||||
void _clutter_actor_meta_set_priority (ClutterActorMeta *meta,
|
||||
gint priority);
|
||||
int _clutter_actor_meta_get_priority (ClutterActorMeta *meta);
|
||||
|
||||
gboolean _clutter_actor_meta_is_internal (ClutterActorMeta *meta);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ACTOR_META_PRIVATE_H__ */
|
||||
|
||||
@@ -23,32 +23,35 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterActorMeta:
|
||||
*
|
||||
* Base class of actor modifiers
|
||||
* SECTION:clutter-actor-meta
|
||||
* @Title: ClutterActorMeta
|
||||
* @Short_Description: Base class of actor modifiers
|
||||
* @See_Also: #ClutterAction, #ClutterConstraint
|
||||
*
|
||||
* #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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* #ClutterActorMeta is available since Clutter 1.4
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter/clutter-actor-meta-private.h"
|
||||
#include "clutter-actor-meta-private.h"
|
||||
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
struct _ClutterActorMetaPrivate
|
||||
{
|
||||
ClutterActor *actor;
|
||||
gulong destroy_id;
|
||||
guint destroy_id;
|
||||
|
||||
gchar *name;
|
||||
|
||||
@@ -78,51 +81,28 @@ static void
|
||||
on_actor_destroy (ClutterActor *actor,
|
||||
ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
priv->actor = NULL;
|
||||
meta->priv->actor = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_meta_real_set_actor (ClutterActorMeta *meta,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
g_warn_if_fail (!priv->actor ||
|
||||
!CLUTTER_ACTOR_IN_PAINT (priv->actor));
|
||||
g_warn_if_fail (!actor || !CLUTTER_ACTOR_IN_PAINT (actor));
|
||||
|
||||
if (priv->actor == actor)
|
||||
if (meta->priv->actor == actor)
|
||||
return;
|
||||
|
||||
g_clear_signal_handler (&priv->destroy_id, priv->actor);
|
||||
if (meta->priv->destroy_id != 0)
|
||||
{
|
||||
g_signal_handler_disconnect (meta->priv->actor, meta->priv->destroy_id);
|
||||
meta->priv->destroy_id = 0;
|
||||
}
|
||||
|
||||
priv->actor = actor;
|
||||
meta->priv->actor = actor;
|
||||
|
||||
if (priv->actor != NULL)
|
||||
priv->destroy_id = g_signal_connect (priv->actor, "destroy",
|
||||
G_CALLBACK (on_actor_destroy),
|
||||
meta);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ACTOR]);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_meta_real_set_enabled (ClutterActorMeta *meta,
|
||||
gboolean is_enabled)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
g_warn_if_fail (!priv->actor ||
|
||||
!CLUTTER_ACTOR_IN_PAINT (priv->actor));
|
||||
|
||||
priv->is_enabled = is_enabled;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ENABLED]);
|
||||
if (meta->priv->actor != NULL)
|
||||
meta->priv->destroy_id = g_signal_connect (meta->priv->actor, "destroy",
|
||||
G_CALLBACK (on_actor_destroy),
|
||||
meta);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -155,21 +135,20 @@ clutter_actor_meta_get_property (GObject *gobject,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (CLUTTER_ACTOR_META (gobject));
|
||||
ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ACTOR:
|
||||
g_value_set_object (value, priv->actor);
|
||||
g_value_set_object (value, meta->priv->actor);
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, priv->name);
|
||||
g_value_set_string (value, meta->priv->name);
|
||||
break;
|
||||
|
||||
case PROP_ENABLED:
|
||||
g_value_set_boolean (value, priv->is_enabled);
|
||||
g_value_set_boolean (value, meta->priv->is_enabled);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -181,11 +160,10 @@ clutter_actor_meta_get_property (GObject *gobject,
|
||||
static void
|
||||
clutter_actor_meta_finalize (GObject *gobject)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (CLUTTER_ACTOR_META (gobject));
|
||||
ClutterActorMetaPrivate *priv = CLUTTER_ACTOR_META (gobject)->priv;
|
||||
|
||||
if (priv->actor != NULL)
|
||||
g_clear_signal_handler (&priv->destroy_id, priv->actor);
|
||||
if (priv->destroy_id != 0 && priv->actor != NULL)
|
||||
g_signal_handler_disconnect (priv->actor, priv->destroy_id);
|
||||
|
||||
g_free (priv->name);
|
||||
|
||||
@@ -198,41 +176,48 @@ clutter_actor_meta_class_init (ClutterActorMetaClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
klass->set_actor = clutter_actor_meta_real_set_actor;
|
||||
klass->set_enabled = clutter_actor_meta_real_set_enabled;
|
||||
|
||||
/**
|
||||
* ClutterActorMeta:actor:
|
||||
*
|
||||
* The #ClutterActor attached to the #ClutterActorMeta instance
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
obj_props[PROP_ACTOR] =
|
||||
g_param_spec_object ("actor", NULL, NULL,
|
||||
g_param_spec_object ("actor",
|
||||
P_("Actor"),
|
||||
P_("The actor attached to the meta"),
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
CLUTTER_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* ClutterActorMeta:name:
|
||||
*
|
||||
* The unique name to access the #ClutterActorMeta
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
obj_props[PROP_NAME] =
|
||||
g_param_spec_string ("name", NULL, NULL,
|
||||
g_param_spec_string ("name",
|
||||
P_("Name"),
|
||||
P_("The name of the meta"),
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* ClutterActorMeta:enabled:
|
||||
*
|
||||
* Whether or not the #ClutterActorMeta is enabled
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
obj_props[PROP_ENABLED] =
|
||||
g_param_spec_boolean ("enabled", NULL, NULL,
|
||||
g_param_spec_boolean ("enabled",
|
||||
P_("Enabled"),
|
||||
P_("Whether the meta is enabled"),
|
||||
TRUE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
gobject_class->finalize = clutter_actor_meta_finalize;
|
||||
gobject_class->set_property = clutter_actor_meta_set_property;
|
||||
@@ -245,11 +230,9 @@ clutter_actor_meta_class_init (ClutterActorMetaClass *klass)
|
||||
void
|
||||
clutter_actor_meta_init (ClutterActorMeta *self)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (self);
|
||||
|
||||
priv->is_enabled = TRUE;
|
||||
priv->priority = CLUTTER_ACTOR_META_PRIORITY_DEFAULT;
|
||||
self->priv = clutter_actor_meta_get_instance_private (self);
|
||||
self->priv->is_enabled = TRUE;
|
||||
self->priv->priority = CLUTTER_ACTOR_META_PRIORITY_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,22 +243,20 @@ clutter_actor_meta_init (ClutterActorMeta *self)
|
||||
* Sets the name of @meta
|
||||
*
|
||||
* The name can be used to identify the #ClutterActorMeta instance
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
clutter_actor_meta_set_name (ClutterActorMeta *meta,
|
||||
const gchar *name)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
|
||||
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
if (g_strcmp0 (priv->name, name) == 0)
|
||||
if (g_strcmp0 (meta->priv->name, name) == 0)
|
||||
return;
|
||||
|
||||
g_free (priv->name);
|
||||
priv->name = g_strdup (name);
|
||||
g_free (meta->priv->name);
|
||||
meta->priv->name = g_strdup (name);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_NAME]);
|
||||
}
|
||||
@@ -284,23 +265,21 @@ clutter_actor_meta_set_name (ClutterActorMeta *meta,
|
||||
* clutter_actor_meta_get_name:
|
||||
* @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
|
||||
* instance, or %NULL if none was set. The returned string is owned
|
||||
* by the #ClutterActorMeta instance and it should not be modified
|
||||
* or freed
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
const gchar *
|
||||
clutter_actor_meta_get_name (ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
|
||||
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
return priv->name;
|
||||
return meta->priv->name;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -309,22 +288,23 @@ clutter_actor_meta_get_name (ClutterActorMeta *meta)
|
||||
* @is_enabled: whether @meta is enabled
|
||||
*
|
||||
* Sets whether @meta should be enabled or not
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
|
||||
gboolean is_enabled)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
|
||||
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
is_enabled = !!is_enabled;
|
||||
|
||||
if (priv->is_enabled == is_enabled)
|
||||
if (meta->priv->is_enabled == is_enabled)
|
||||
return;
|
||||
|
||||
CLUTTER_ACTOR_META_GET_CLASS (meta)->set_enabled (meta, is_enabled);
|
||||
meta->priv->is_enabled = is_enabled;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ENABLED]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -334,17 +314,15 @@ clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
|
||||
* Retrieves whether @meta is enabled
|
||||
*
|
||||
* Return value: %TRUE if the #ClutterActorMeta instance is enabled
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
gboolean
|
||||
clutter_actor_meta_get_enabled (ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), FALSE);
|
||||
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
return priv->is_enabled;
|
||||
return meta->priv->is_enabled;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -354,8 +332,10 @@ clutter_actor_meta_get_enabled (ClutterActorMeta *meta)
|
||||
*
|
||||
* Sets or unsets a back pointer to the #ClutterActor that owns
|
||||
* the @meta
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
static void
|
||||
void
|
||||
_clutter_actor_meta_set_actor (ClutterActorMeta *meta,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
@@ -369,61 +349,49 @@ _clutter_actor_meta_set_actor (ClutterActorMeta *meta,
|
||||
* clutter_actor_meta_get_actor:
|
||||
* @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
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_actor_meta_get_actor (ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
|
||||
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
return priv->actor;
|
||||
return meta->priv->actor;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_actor_meta_set_priority (ClutterActorMeta *meta,
|
||||
gint priority)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
|
||||
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
/* This property shouldn't be modified after the actor meta is in
|
||||
use because ClutterMetaGroup doesn't resort the list when it
|
||||
changes. If we made the priority public then we could either make
|
||||
the priority a construct-only property or listen for
|
||||
notifications on the property from the ClutterMetaGroup and
|
||||
resort. */
|
||||
g_return_if_fail (priv->actor == NULL);
|
||||
g_return_if_fail (meta->priv->actor == NULL);
|
||||
|
||||
priv->priority = priority;
|
||||
meta->priv->priority = priority;
|
||||
}
|
||||
|
||||
static gint
|
||||
gint
|
||||
_clutter_actor_meta_get_priority (ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), 0);
|
||||
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
return priv->priority;
|
||||
return meta->priv->priority;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gboolean
|
||||
_clutter_actor_meta_is_internal (ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
gint priority = priv->priority;
|
||||
gint priority = meta->priv->priority;
|
||||
|
||||
return (priority <= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_LOW ||
|
||||
priority >= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_HIGH);
|
||||
@@ -433,7 +401,7 @@ _clutter_actor_meta_is_internal (ClutterActorMeta *meta)
|
||||
* ClutterMetaGroup: a collection of ClutterActorMeta instances
|
||||
*/
|
||||
|
||||
G_DEFINE_FINAL_TYPE (ClutterMetaGroup, _clutter_meta_group, G_TYPE_OBJECT);
|
||||
G_DEFINE_TYPE (ClutterMetaGroup, _clutter_meta_group, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
_clutter_meta_group_dispose (GObject *gobject)
|
||||
@@ -470,21 +438,19 @@ void
|
||||
_clutter_meta_group_add_meta (ClutterMetaGroup *group,
|
||||
ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
GList *prev = NULL, *l;
|
||||
|
||||
if (priv->actor != NULL)
|
||||
if (meta->priv->actor != NULL)
|
||||
{
|
||||
g_warning ("The meta of type '%s' with name '%s' is "
|
||||
"already attached to actor '%s'",
|
||||
G_OBJECT_TYPE_NAME (meta),
|
||||
priv->name != NULL
|
||||
? priv->name
|
||||
meta->priv->name != NULL
|
||||
? meta->priv->name
|
||||
: "<unknown>",
|
||||
clutter_actor_get_name (priv->actor) != NULL
|
||||
? clutter_actor_get_name (priv->actor)
|
||||
: G_OBJECT_TYPE_NAME (priv->actor));
|
||||
clutter_actor_get_name (meta->priv->actor) != NULL
|
||||
? clutter_actor_get_name (meta->priv->actor)
|
||||
: G_OBJECT_TYPE_NAME (meta->priv->actor));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -520,16 +486,13 @@ void
|
||||
_clutter_meta_group_remove_meta (ClutterMetaGroup *group,
|
||||
ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
if (priv->actor != group->actor)
|
||||
if (meta->priv->actor != group->actor)
|
||||
{
|
||||
g_warning ("The meta of type '%s' with name '%s' is not "
|
||||
"attached to the actor '%s'",
|
||||
G_OBJECT_TYPE_NAME (meta),
|
||||
priv->name != NULL
|
||||
? priv->name
|
||||
meta->priv->name != NULL
|
||||
? meta->priv->name
|
||||
: "<unknown>",
|
||||
clutter_actor_get_name (group->actor) != NULL
|
||||
? clutter_actor_get_name (group->actor)
|
||||
@@ -672,10 +635,8 @@ _clutter_meta_group_get_meta (ClutterMetaGroup *group,
|
||||
for (l = group->meta; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterActorMeta *meta = l->data;
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
if (g_strcmp0 (priv->name, name) == 0)
|
||||
if (g_strcmp0 (meta->priv->name, name) == 0)
|
||||
return meta;
|
||||
}
|
||||
|
||||
@@ -695,8 +656,6 @@ _clutter_meta_group_get_meta (ClutterMetaGroup *group,
|
||||
const gchar *
|
||||
_clutter_actor_meta_get_debug_name (ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
return priv->name != NULL ? priv->name : G_OBJECT_TYPE_NAME (meta);
|
||||
return meta->priv->name != NULL ? meta->priv->name
|
||||
: G_OBJECT_TYPE_NAME (meta);
|
||||
}
|
||||
|
||||
@@ -22,23 +22,42 @@
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_ACTOR_META_H__
|
||||
#define __CLUTTER_ACTOR_META_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
#include <clutter/clutter-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_ACTOR_META (clutter_actor_meta_get_type ())
|
||||
#define CLUTTER_TYPE_ACTOR_META (clutter_actor_meta_get_type ())
|
||||
#define CLUTTER_ACTOR_META(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMeta))
|
||||
#define CLUTTER_IS_ACTOR_META(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTOR_META))
|
||||
#define CLUTTER_ACTOR_META_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass))
|
||||
#define CLUTTER_IS_ACTOR_META_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTOR_META))
|
||||
#define CLUTTER_ACTOR_META_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass))
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterActorMeta, clutter_actor_meta,
|
||||
CLUTTER, ACTOR_META, GInitiallyUnowned);
|
||||
typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate;
|
||||
typedef struct _ClutterActorMetaClass ClutterActorMetaClass;
|
||||
|
||||
typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate;
|
||||
/**
|
||||
* ClutterActorMeta:
|
||||
*
|
||||
* The #ClutterActorMeta structure contains only
|
||||
* private data and should be accessed using the provided API
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _ClutterActorMeta
|
||||
{
|
||||
/*< private >*/
|
||||
GInitiallyUnowned parent_instance;
|
||||
|
||||
ClutterActorMetaPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterActorMetaClass:
|
||||
@@ -47,6 +66,8 @@ typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate;
|
||||
*
|
||||
* The #ClutterActorMetaClass structure contains
|
||||
* only private data
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _ClutterActorMetaClass
|
||||
{
|
||||
@@ -66,10 +87,19 @@ struct _ClutterActorMetaClass
|
||||
void (* set_actor) (ClutterActorMeta *meta,
|
||||
ClutterActor *actor);
|
||||
|
||||
void (* set_enabled) (ClutterActorMeta *meta,
|
||||
gboolean is_enabled);
|
||||
/*< private >*/
|
||||
void (* _clutter_meta1) (void);
|
||||
void (* _clutter_meta2) (void);
|
||||
void (* _clutter_meta3) (void);
|
||||
void (* _clutter_meta4) (void);
|
||||
void (* _clutter_meta5) (void);
|
||||
void (* _clutter_meta6) (void);
|
||||
void (* _clutter_meta7) (void);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_actor_meta_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_meta_set_name (ClutterActorMeta *meta,
|
||||
const gchar *name);
|
||||
@@ -85,3 +115,5 @@ CLUTTER_EXPORT
|
||||
ClutterActor * clutter_actor_meta_get_actor (ClutterActorMeta *meta);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ACTOR_META_H__ */
|
||||
|
||||
@@ -19,44 +19,29 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_ACTOR_PRIVATE_H__
|
||||
#define __CLUTTER_ACTOR_PRIVATE_H__
|
||||
|
||||
#include "clutter/clutter-actor.h"
|
||||
#include "clutter/clutter-grab.h"
|
||||
#include <clutter/clutter-actor.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*
|
||||
* Auxiliary define, in order to get the clutter actor from the AtkObject using
|
||||
* AtkGObject methods
|
||||
/*< 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)
|
||||
*
|
||||
*/
|
||||
#define CLUTTER_ACTOR_FROM_ACCESSIBLE(accessible) \
|
||||
(CLUTTER_ACTOR (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible))))
|
||||
|
||||
/**
|
||||
* ClutterActorFlags:
|
||||
* @CLUTTER_ACTOR_MAPPED: the actor will be painted (is visible, and inside
|
||||
* a toplevel, and all parents visible)
|
||||
* @CLUTTER_ACTOR_REALIZED: the resources associated to the actor have been
|
||||
* allocated
|
||||
* @CLUTTER_ACTOR_REACTIVE: the actor 'reacts' to mouse events emitting event
|
||||
* signals
|
||||
* @CLUTTER_ACTOR_VISIBLE: the actor has been shown by the application program
|
||||
* @CLUTTER_ACTOR_NO_LAYOUT: the actor provides an explicit layout management
|
||||
* policy for its children; this flag will prevent Clutter from automatic
|
||||
* queueing of relayout and will defer all layouting to the actor itself
|
||||
* Flags passed to the clutter_actor_queue_redraw_with_clip ()
|
||||
* function
|
||||
*
|
||||
* Flags used to signal the state of an actor.
|
||||
* Since: 1.6
|
||||
*/
|
||||
typedef enum /*< prefix=CLUTTER_ACTOR >*/
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_ACTOR_MAPPED = 1 << 1,
|
||||
CLUTTER_ACTOR_REALIZED = 1 << 2,
|
||||
CLUTTER_ACTOR_REACTIVE = 1 << 3,
|
||||
CLUTTER_ACTOR_VISIBLE = 1 << 4,
|
||||
CLUTTER_ACTOR_NO_LAYOUT = 1 << 5
|
||||
} ClutterActorFlags;
|
||||
CLUTTER_REDRAW_CLIPPED_TO_ALLOCATION = 1 << 0
|
||||
} ClutterRedrawFlags;
|
||||
|
||||
/*< private >
|
||||
* ClutterActorTraverseFlags:
|
||||
@@ -115,7 +100,9 @@ typedef ClutterActorTraverseVisitFlags (*ClutterTraverseCallback) (ClutterActor
|
||||
* @user_data: The private data specified when starting the iteration
|
||||
*
|
||||
* A generic callback for iterating over actor, such as with
|
||||
* _clutter_actor_foreach_child.
|
||||
* _clutter_actor_foreach_child. The difference when compared to
|
||||
* #ClutterCallback is that it returns a boolean so it is possible to break
|
||||
* out of an iteration early.
|
||||
*
|
||||
* Return value: %TRUE to continue iterating or %FALSE to break iteration
|
||||
* early.
|
||||
@@ -123,12 +110,35 @@ typedef ClutterActorTraverseVisitFlags (*ClutterTraverseCallback) (ClutterActor
|
||||
typedef gboolean (*ClutterForeachCallback) (ClutterActor *actor,
|
||||
gpointer user_data);
|
||||
|
||||
typedef struct _AnchorCoord AnchorCoord;
|
||||
typedef struct _SizeRequest SizeRequest;
|
||||
|
||||
typedef struct _ClutterLayoutInfo ClutterLayoutInfo;
|
||||
typedef struct _ClutterTransformInfo ClutterTransformInfo;
|
||||
typedef struct _ClutterAnimationInfo ClutterAnimationInfo;
|
||||
|
||||
/* Internal helper struct to represent a point that can be stored in
|
||||
either direct pixel coordinates or as a fraction of the actor's
|
||||
size. It is used for the anchor point, scale center and rotation
|
||||
centers. */
|
||||
struct _AnchorCoord
|
||||
{
|
||||
gboolean is_fractional;
|
||||
|
||||
union
|
||||
{
|
||||
/* Used when is_fractional == TRUE */
|
||||
struct
|
||||
{
|
||||
gdouble x;
|
||||
gdouble y;
|
||||
} fraction;
|
||||
|
||||
/* Use when is_fractional == FALSE */
|
||||
ClutterVertex units;
|
||||
} v;
|
||||
};
|
||||
|
||||
struct _SizeRequest
|
||||
{
|
||||
guint age;
|
||||
@@ -153,7 +163,7 @@ struct _SizeRequest
|
||||
struct _ClutterLayoutInfo
|
||||
{
|
||||
/* fixed position coordinates */
|
||||
graphene_point_t fixed_pos;
|
||||
ClutterPoint fixed_pos;
|
||||
|
||||
ClutterMargin margin;
|
||||
|
||||
@@ -163,8 +173,8 @@ struct _ClutterLayoutInfo
|
||||
guint x_expand : 1;
|
||||
guint y_expand : 1;
|
||||
|
||||
graphene_size_t minimum;
|
||||
graphene_size_t natural;
|
||||
ClutterSize minimum;
|
||||
ClutterSize natural;
|
||||
};
|
||||
|
||||
const ClutterLayoutInfo * _clutter_actor_get_layout_info_or_defaults (ClutterActor *self);
|
||||
@@ -173,30 +183,39 @@ ClutterLayoutInfo * _clutter_actor_peek_layout_info
|
||||
|
||||
struct _ClutterTransformInfo
|
||||
{
|
||||
/* rotation */
|
||||
/* rotation (angle and center) */
|
||||
gdouble rx_angle;
|
||||
AnchorCoord rx_center;
|
||||
|
||||
gdouble ry_angle;
|
||||
AnchorCoord ry_center;
|
||||
|
||||
gdouble rz_angle;
|
||||
AnchorCoord rz_center;
|
||||
|
||||
/* scaling */
|
||||
gdouble scale_x;
|
||||
gdouble scale_y;
|
||||
gdouble scale_z;
|
||||
AnchorCoord scale_center;
|
||||
|
||||
/* anchor point */
|
||||
AnchorCoord anchor;
|
||||
|
||||
/* translation */
|
||||
graphene_point3d_t translation;
|
||||
ClutterVertex translation;
|
||||
|
||||
/* z_position */
|
||||
gfloat z_position;
|
||||
|
||||
/* transformation center */
|
||||
graphene_point_t pivot;
|
||||
ClutterPoint pivot;
|
||||
gfloat pivot_z;
|
||||
|
||||
graphene_matrix_t transform;
|
||||
CoglMatrix transform;
|
||||
guint transform_set : 1;
|
||||
|
||||
graphene_matrix_t child_transform;
|
||||
CoglMatrix child_transform;
|
||||
guint child_transform_set : 1;
|
||||
};
|
||||
|
||||
@@ -223,6 +242,9 @@ ClutterAnimationInfo * _clutter_actor_get_animation_info
|
||||
ClutterTransition * _clutter_actor_create_transition (ClutterActor *self,
|
||||
GParamSpec *pspec,
|
||||
...);
|
||||
ClutterTransition * _clutter_actor_get_transition (ClutterActor *self,
|
||||
GParamSpec *pspec);
|
||||
|
||||
gboolean _clutter_actor_foreach_child (ClutterActor *self,
|
||||
ClutterForeachCallback callback,
|
||||
gpointer user_data);
|
||||
@@ -233,11 +255,15 @@ void _clutter_actor_traverse
|
||||
gpointer user_data);
|
||||
ClutterActor * _clutter_actor_get_stage_internal (ClutterActor *actor);
|
||||
|
||||
void _clutter_actor_apply_modelview_transform (ClutterActor *self,
|
||||
graphene_matrix_t *matrix);
|
||||
void _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self,
|
||||
ClutterActor *ancestor,
|
||||
graphene_matrix_t *matrix);
|
||||
void _clutter_actor_apply_modelview_transform (ClutterActor *self,
|
||||
CoglMatrix *matrix);
|
||||
void _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self,
|
||||
ClutterActor *ancestor,
|
||||
CoglMatrix *matrix);
|
||||
|
||||
void _clutter_actor_rerealize (ClutterActor *self,
|
||||
ClutterCallback callback,
|
||||
gpointer data);
|
||||
|
||||
void _clutter_actor_set_in_clone_paint (ClutterActor *self,
|
||||
gboolean is_in_clone_paint);
|
||||
@@ -251,55 +277,53 @@ void _clutter_actor_set_enable_paint_unmapped
|
||||
void _clutter_actor_set_has_pointer (ClutterActor *self,
|
||||
gboolean has_pointer);
|
||||
|
||||
void _clutter_actor_set_has_key_focus (ClutterActor *self,
|
||||
gboolean has_key_focus);
|
||||
|
||||
void _clutter_actor_queue_redraw_with_clip (ClutterActor *self,
|
||||
ClutterRedrawFlags flags,
|
||||
const ClutterPaintVolume *clip_volume);
|
||||
void _clutter_actor_queue_redraw_full (ClutterActor *self,
|
||||
ClutterRedrawFlags flags,
|
||||
const ClutterPaintVolume *volume,
|
||||
ClutterEffect *effect);
|
||||
|
||||
void _clutter_actor_finish_queue_redraw (ClutterActor *self,
|
||||
ClutterPaintVolume *clip);
|
||||
|
||||
gboolean _clutter_actor_set_default_paint_volume (ClutterActor *self,
|
||||
GType check_gtype,
|
||||
ClutterPaintVolume *volume);
|
||||
|
||||
const char * _clutter_actor_get_debug_name (ClutterActor *self);
|
||||
const gchar * _clutter_actor_get_debug_name (ClutterActor *self);
|
||||
|
||||
void _clutter_actor_push_clone_paint (void);
|
||||
void _clutter_actor_pop_clone_paint (void);
|
||||
|
||||
guint32 _clutter_actor_get_pick_id (ClutterActor *self);
|
||||
|
||||
void _clutter_actor_shader_pre_paint (ClutterActor *actor,
|
||||
gboolean repeat);
|
||||
void _clutter_actor_shader_post_paint (ClutterActor *actor);
|
||||
|
||||
ClutterActorAlign _clutter_actor_get_effective_x_align (ClutterActor *self);
|
||||
|
||||
void _clutter_actor_handle_event (ClutterActor *actor,
|
||||
const ClutterEvent *event);
|
||||
|
||||
void _clutter_actor_attach_clone (ClutterActor *actor,
|
||||
ClutterActor *clone);
|
||||
void _clutter_actor_detach_clone (ClutterActor *actor,
|
||||
ClutterActor *clone);
|
||||
void _clutter_actor_queue_redraw_on_clones (ClutterActor *actor);
|
||||
void _clutter_actor_queue_relayout_on_clones (ClutterActor *actor);
|
||||
void _clutter_actor_queue_only_relayout (ClutterActor *actor);
|
||||
void clutter_actor_clear_stage_views_recursive (ClutterActor *actor,
|
||||
gboolean stop_transitions);
|
||||
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);
|
||||
|
||||
void clutter_actor_finish_layout (ClutterActor *self,
|
||||
int phase);
|
||||
|
||||
void clutter_actor_queue_immediate_relayout (ClutterActor *self);
|
||||
|
||||
gboolean clutter_actor_is_painting_unmapped (ClutterActor *self);
|
||||
|
||||
void clutter_actor_attach_grab (ClutterActor *actor,
|
||||
ClutterGrab *grab);
|
||||
void clutter_actor_detach_grab (ClutterActor *actor,
|
||||
ClutterGrab *grab);
|
||||
|
||||
void clutter_actor_collect_event_actors (ClutterActor *self,
|
||||
ClutterActor *deepmost,
|
||||
GPtrArray *actors);
|
||||
|
||||
const GList * clutter_actor_peek_actions (ClutterActor *self);
|
||||
|
||||
void clutter_actor_set_implicitly_grabbed (ClutterActor *actor,
|
||||
gboolean is_implicitly_grabbed);
|
||||
|
||||
AtkStateSet * clutter_actor_get_accessible_state (ClutterActor *actor);
|
||||
ClutterPaintNode * clutter_actor_create_texture_paint_node (ClutterActor *self,
|
||||
CoglTexture *texture);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ACTOR_PRIVATE_H__ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,8 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_ACTOR_H__
|
||||
#define __CLUTTER_ACTOR_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
@@ -30,16 +31,14 @@
|
||||
|
||||
/* clutter-actor.h */
|
||||
|
||||
#include <atk/atk.h>
|
||||
#include <gio/gio.h>
|
||||
#include <pango/pango.h>
|
||||
#include <atk/atk.h>
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
#include "clutter/clutter-event.h"
|
||||
#include "clutter/clutter-paint-context.h"
|
||||
#include "clutter/clutter-pick-context.h"
|
||||
#include "mtk/mtk.h"
|
||||
#include <clutter/clutter-types.h>
|
||||
#include <clutter/clutter-event.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -50,12 +49,79 @@ G_BEGIN_DECLS
|
||||
#define CLUTTER_IS_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTOR))
|
||||
#define CLUTTER_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTOR, ClutterActorClass))
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActor, g_object_unref)
|
||||
/**
|
||||
* CLUTTER_ACTOR_SET_FLAGS:
|
||||
* @a: a #ClutterActor
|
||||
* @f: the #ClutterActorFlags to set
|
||||
*
|
||||
* Sets the given flags on a #ClutterActor
|
||||
*
|
||||
* Deprecated: 1.24: Changing flags directly is heavily discouraged in
|
||||
* newly written code. #ClutterActor will take care of setting the
|
||||
* internal state.
|
||||
*/
|
||||
#define CLUTTER_ACTOR_SET_FLAGS(a,f) \
|
||||
CLUTTER_MACRO_DEPRECATED \
|
||||
(((ClutterActor*)(a))->flags |= (f))
|
||||
|
||||
/**
|
||||
* CLUTTER_ACTOR_UNSET_FLAGS:
|
||||
* @a: a #ClutterActor
|
||||
* @f: the #ClutterActorFlags to unset
|
||||
*
|
||||
* Unsets the given flags on a #ClutterActor
|
||||
*
|
||||
* Deprecated: 1.24: Changing flags directly is heavily discouraged in
|
||||
* newly written code. #ClutterActor will take care of unsetting the
|
||||
* internal state.
|
||||
*/
|
||||
#define CLUTTER_ACTOR_UNSET_FLAGS(a,f) \
|
||||
CLUTTER_MACRO_DEPRECATED \
|
||||
(((ClutterActor*)(a))->flags &= ~(f))
|
||||
|
||||
#define CLUTTER_ACTOR_IS_MAPPED(a) \
|
||||
CLUTTER_MACRO_DEPRECATED_FOR ("Deprecated macro. Use clutter_actor_is_mapped instead") \
|
||||
((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_MAPPED) != FALSE)
|
||||
|
||||
#define CLUTTER_ACTOR_IS_REALIZED(a) \
|
||||
CLUTTER_MACRO_DEPRECATED_FOR ("Deprecated macro. Use clutter_actor_is_realized instead") \
|
||||
((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_REALIZED) != FALSE)
|
||||
|
||||
#define CLUTTER_ACTOR_IS_VISIBLE(a) \
|
||||
CLUTTER_MACRO_DEPRECATED_FOR ("Deprecated macro. Use clutter_actor_is_visible instead") \
|
||||
((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_VISIBLE) != FALSE)
|
||||
|
||||
#define CLUTTER_ACTOR_IS_REACTIVE(a) \
|
||||
CLUTTER_MACRO_DEPRECATED_FOR ("Deprecated macro. Use clutter_actor_get_reactive instead") \
|
||||
((((ClutterActor*)(a))->flags & CLUTTER_ACTOR_REACTIVE) != FALSE)
|
||||
|
||||
typedef struct _ClutterActorClass ClutterActorClass;
|
||||
typedef struct _ClutterActorPrivate ClutterActorPrivate;
|
||||
|
||||
/**
|
||||
* ClutterCallback:
|
||||
* @actor: a #ClutterActor
|
||||
* @data: (closure): user data
|
||||
*
|
||||
* Generic callback
|
||||
*/
|
||||
typedef void (*ClutterCallback) (ClutterActor *actor,
|
||||
gpointer data);
|
||||
|
||||
/**
|
||||
* CLUTTER_CALLBACK:
|
||||
* @f: a function
|
||||
*
|
||||
* Convenience macro to cast a function to #ClutterCallback
|
||||
*/
|
||||
#define CLUTTER_CALLBACK(f) ((ClutterCallback) (f))
|
||||
|
||||
/**
|
||||
* ClutterActor:
|
||||
* @flags: #ClutterActorFlags
|
||||
*
|
||||
* Base class for actors.
|
||||
*/
|
||||
struct _ClutterActor
|
||||
{
|
||||
/*< private >*/
|
||||
@@ -63,7 +129,6 @@ struct _ClutterActor
|
||||
|
||||
/*< public >*/
|
||||
guint32 flags;
|
||||
AtkRole accessible_role;
|
||||
|
||||
/*< private >*/
|
||||
guint32 private_flags;
|
||||
@@ -73,9 +138,14 @@ struct _ClutterActor
|
||||
|
||||
/**
|
||||
* ClutterActorClass:
|
||||
* @show: signal class handler for [signal@Clutter.Actor::show]; it must chain
|
||||
* @show: signal class handler for #ClutterActor::show; it must chain
|
||||
* up to the parent's implementation
|
||||
* @hide: signal class handler for [signal@Clutter.Actor::hide]; it must chain
|
||||
* @show_all: virtual function for containers and composite actors, to
|
||||
* determine which children should be shown when calling
|
||||
* clutter_actor_show_all() on the actor. Defaults to calling
|
||||
* clutter_actor_show(). This virtual function is deprecated and it
|
||||
* should not be overridden.
|
||||
* @hide: signal class handler for #ClutterActor::hide; it must chain
|
||||
* up to the parent's implementation
|
||||
* @hide_all: virtual function for containers and composite actors, to
|
||||
* determine which children should be shown when calling
|
||||
@@ -103,42 +173,35 @@ struct _ClutterActor
|
||||
* @get_preferred_height: virtual function, used when querying the minimum
|
||||
* and natural heights of an actor for a given width; it is used by
|
||||
* clutter_actor_get_preferred_height()
|
||||
* @allocate: virtual function, used when setting the coordinates of an
|
||||
* actor; it is used by clutter_actor_allocate(); when overriding this
|
||||
* function without chaining up, clutter_actor_set_allocation() must be
|
||||
* called and children must be allocated by the implementation, when
|
||||
* chaining up though, those things will be done by the parent's
|
||||
* implementation.
|
||||
* @allocate: virtual function, used when settings the coordinates of an
|
||||
* actor; it is used by clutter_actor_allocate(); it must chain up to
|
||||
* the parent's implementation, or call clutter_actor_set_allocation()
|
||||
* @apply_transform: virtual function, used when applying the transformations
|
||||
* to an actor before painting it or when transforming coordinates or
|
||||
* the allocation; if the transformation calculated by this function may
|
||||
* have changed, the cached transformation must be invalidated by calling
|
||||
* clutter_actor_invalidate_transform(); it must chain up to the parent's
|
||||
* implementation
|
||||
* @parent_set: signal class handler for the [signal@Clutter.Actor::parent-set]
|
||||
* @destroy: signal class handler for [signal@Clutter.Actor::destroy]. It must
|
||||
* the allocation; it must chain up to the parent's implementation
|
||||
* @parent_set: signal class handler for the #ClutterActor::parent-set
|
||||
* @destroy: signal class handler for #ClutterActor::destroy. It must
|
||||
* chain up to the parent's implementation
|
||||
* @pick: virtual function, used to draw an outline of the actor with
|
||||
* the given color
|
||||
* @event: class handler for [signal@Clutter.Actor::event]
|
||||
* @button_press_event: class handler for [signal@Clutter.Actor::button-press-event]
|
||||
* @queue_redraw: class handler for #ClutterActor::queue-redraw
|
||||
* @event: class handler for #ClutterActor::event
|
||||
* @button_press_event: class handler for #ClutterActor::button-press-event
|
||||
* @button_release_event: class handler for
|
||||
* [signal@Clutter.Actor::button-release-event]
|
||||
* @scroll_event: signal class closure for [signal@Clutter.Actor::scroll-event]
|
||||
* @key_press_event: signal class closure for [signal@Clutter.Actor::key-press-event]
|
||||
* #ClutterActor::button-release-event
|
||||
* @scroll_event: signal class closure for #ClutterActor::scroll-event
|
||||
* @key_press_event: signal class closure for #ClutterActor::key-press-event
|
||||
* @key_release_event: signal class closure for
|
||||
* [signal@Clutter.Actor::key-release-event]
|
||||
* @motion_event: signal class closure for [signal@Clutter.Actor::motion-event]
|
||||
* @enter_event: signal class closure for [signal@Clutter.Actor::enter-event]
|
||||
* @leave_event: signal class closure for [signal@Clutter.Actor::leave-event]
|
||||
* @captured_event: signal class closure for [signal@Clutter.Actor::captured-event]
|
||||
* @key_focus_in: signal class closure for [signal@Clutter.Actor::key-focus-in]
|
||||
* @key_focus_out: signal class closure for [signal@Clutter.Actor::key-focus-out]
|
||||
* @queue_relayout: class handler for [signal@Clutter.Actor::queue-relayout]
|
||||
* #ClutterActor::key-release-event
|
||||
* @motion_event: signal class closure for #ClutterActor::motion-event
|
||||
* @enter_event: signal class closure for #ClutterActor::enter-event
|
||||
* @leave_event: signal class closure for #ClutterActor::leave-event
|
||||
* @captured_event: signal class closure for #ClutterActor::captured-event
|
||||
* @key_focus_in: signal class closure for #ClutterActor::key-focus-in
|
||||
* @key_focus_out: signal class closure for #ClutterActor::key-focus-out
|
||||
* @queue_relayout: class handler for #ClutterActor::queue-relayout
|
||||
* @get_accessible: virtual function, returns the accessible object that
|
||||
* describes the actor to an assistive technology.
|
||||
* @get_accessible_type: returns the type of the accessible object that
|
||||
* describes the actor to an assistive technology.
|
||||
* @get_paint_volume: virtual function, for sub-classes to define their
|
||||
* #ClutterPaintVolume
|
||||
* @has_overlaps: virtual function for
|
||||
@@ -147,7 +210,7 @@ struct _ClutterActor
|
||||
* clutter_actor_set_offscreen_redirect() for details.
|
||||
* @paint_node: virtual function for creating paint nodes and attaching
|
||||
* them to the render tree
|
||||
* @touch_event: signal class closure for [signal@Clutter.Actor::touch-event]
|
||||
* @touch_event: signal class closure for #ClutterActor::touch-event
|
||||
*
|
||||
* Base class for actors.
|
||||
*/
|
||||
@@ -158,20 +221,24 @@ struct _ClutterActorClass
|
||||
|
||||
/*< public >*/
|
||||
void (* show) (ClutterActor *self);
|
||||
void (* show_all) (ClutterActor *self);
|
||||
void (* hide) (ClutterActor *self);
|
||||
void (* hide_all) (ClutterActor *self);
|
||||
void (* realize) (ClutterActor *self);
|
||||
void (* unrealize) (ClutterActor *self);
|
||||
void (* map) (ClutterActor *self);
|
||||
void (* unmap) (ClutterActor *self);
|
||||
void (* paint) (ClutterActor *self,
|
||||
ClutterPaintContext *paint_context);
|
||||
void (* paint) (ClutterActor *self);
|
||||
void (* parent_set) (ClutterActor *actor,
|
||||
ClutterActor *old_parent);
|
||||
|
||||
void (* destroy) (ClutterActor *self);
|
||||
void (* pick) (ClutterActor *actor,
|
||||
ClutterPickContext *pick_context);
|
||||
const ClutterColor *color);
|
||||
|
||||
gboolean (* queue_redraw) (ClutterActor *actor,
|
||||
ClutterActor *leaf_that_queued,
|
||||
ClutterPaintVolume *paint_volume);
|
||||
|
||||
/* size negotiation */
|
||||
void (* get_preferred_width) (ClutterActor *self,
|
||||
@@ -183,31 +250,32 @@ struct _ClutterActorClass
|
||||
gfloat *min_height_p,
|
||||
gfloat *natural_height_p);
|
||||
void (* allocate) (ClutterActor *self,
|
||||
const ClutterActorBox *box);
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags);
|
||||
|
||||
/* transformations */
|
||||
void (* apply_transform) (ClutterActor *actor,
|
||||
graphene_matrix_t *matrix);
|
||||
ClutterMatrix *matrix);
|
||||
|
||||
/* event signals */
|
||||
gboolean (* event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
gboolean (* button_press_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
ClutterButtonEvent *event);
|
||||
gboolean (* button_release_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
ClutterButtonEvent *event);
|
||||
gboolean (* scroll_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
ClutterScrollEvent *event);
|
||||
gboolean (* key_press_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
ClutterKeyEvent *event);
|
||||
gboolean (* key_release_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
ClutterKeyEvent *event);
|
||||
gboolean (* motion_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
ClutterMotionEvent *event);
|
||||
gboolean (* enter_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
ClutterCrossingEvent *event);
|
||||
gboolean (* leave_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
ClutterCrossingEvent *event);
|
||||
gboolean (* captured_event) (ClutterActor *actor,
|
||||
ClutterEvent *event);
|
||||
void (* key_focus_in) (ClutterActor *actor);
|
||||
@@ -217,7 +285,6 @@ struct _ClutterActorClass
|
||||
|
||||
/* accessibility support */
|
||||
AtkObject * (* get_accessible) (ClutterActor *self);
|
||||
GType (* get_accessible_type) (void);
|
||||
|
||||
gboolean (* get_paint_volume) (ClutterActor *actor,
|
||||
ClutterPaintVolume *volume);
|
||||
@@ -225,22 +292,14 @@ struct _ClutterActorClass
|
||||
gboolean (* has_overlaps) (ClutterActor *self);
|
||||
|
||||
void (* paint_node) (ClutterActor *self,
|
||||
ClutterPaintNode *root,
|
||||
ClutterPaintContext *paint_context);
|
||||
ClutterPaintNode *root);
|
||||
|
||||
gboolean (* touch_event) (ClutterActor *self,
|
||||
ClutterEvent *event);
|
||||
void (* resource_scale_changed) (ClutterActor *self);
|
||||
float (* calculate_resource_scale) (ClutterActor *self,
|
||||
int phase);
|
||||
ClutterTouchEvent *event);
|
||||
|
||||
void (* child_added) (ClutterActor *self,
|
||||
ClutterActor *child);
|
||||
void (* child_removed) (ClutterActor *self,
|
||||
ClutterActor *child);
|
||||
|
||||
/* private */
|
||||
GType layout_manager_type;
|
||||
/*< private >*/
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[26];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -251,13 +310,17 @@ struct _ClutterActorClass
|
||||
*
|
||||
* The contents of the #ClutterActorIter structure
|
||||
* are private and should only be accessed using the provided API.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
struct _ClutterActorIter
|
||||
{
|
||||
/*< private >*/
|
||||
gpointer CLUTTER_PRIVATE_FIELD (dummy1);
|
||||
gpointer CLUTTER_PRIVATE_FIELD (dummy2);
|
||||
gint CLUTTER_PRIVATE_FIELD (dummy3);
|
||||
gpointer CLUTTER_PRIVATE_FIELD (dummy3);
|
||||
gint CLUTTER_PRIVATE_FIELD (dummy4);
|
||||
gpointer CLUTTER_PRIVATE_FIELD (dummy5);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
@@ -266,6 +329,14 @@ GType clutter_actor_get_type (void) G_GNUC_CONST;
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_actor_new (void);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_flags (ClutterActor *self,
|
||||
ClutterActorFlags flags);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_unset_flags (ClutterActor *self,
|
||||
ClutterActorFlags flags);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActorFlags clutter_actor_get_flags (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_show (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
@@ -279,25 +350,14 @@ void clutter_actor_map
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_unmap (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_paint (ClutterActor *self,
|
||||
ClutterPaintContext *paint_context);
|
||||
void clutter_actor_paint (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_continue_paint (ClutterActor *self,
|
||||
ClutterPaintContext *paint_context);
|
||||
CLUTTER_EXPORT
|
||||
ClutterPaintNode * clutter_actor_create_texture_paint_node (ClutterActor *self,
|
||||
CoglTexture *texture);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_pick (ClutterActor *actor,
|
||||
ClutterPickContext *pick_context);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_continue_pick (ClutterActor *actor,
|
||||
ClutterPickContext *pick_context);
|
||||
void clutter_actor_continue_paint (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_queue_redraw (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_queue_redraw_with_clip (ClutterActor *self,
|
||||
const MtkRectangle *clip);
|
||||
void clutter_actor_queue_redraw_with_clip (ClutterActor *self,
|
||||
const cairo_rectangle_int_t *clip);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_queue_relayout (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
@@ -308,26 +368,8 @@ void clutter_actor_set_name
|
||||
CLUTTER_EXPORT
|
||||
const gchar * clutter_actor_get_name (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_accessible_role (ClutterActor *self,
|
||||
AtkRole role);
|
||||
CLUTTER_EXPORT
|
||||
AtkRole clutter_actor_get_accessible_role (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_accessible_name (ClutterActor *self,
|
||||
const gchar *name);
|
||||
CLUTTER_EXPORT
|
||||
const gchar * clutter_actor_get_accessible_name (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
AtkObject * clutter_actor_get_accessible (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_accessible (ClutterActor *self,
|
||||
AtkObject *accessible);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_add_accessible_state (ClutterActor *actor,
|
||||
AtkStateType state);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_remove_accessible_state (ClutterActor *actor,
|
||||
AtkStateType state);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_is_visible (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
@@ -337,11 +379,6 @@ gboolean clutter_actor_is_realized
|
||||
|
||||
/* Size negotiation */
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_no_layout (ClutterActor *actor,
|
||||
gboolean no_layout);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_is_no_layout (ClutterActor *actor);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_request_mode (ClutterActor *self,
|
||||
ClutterRequestMode mode);
|
||||
CLUTTER_EXPORT
|
||||
@@ -364,31 +401,38 @@ void clutter_actor_get_preferred_size
|
||||
gfloat *natural_height_p);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box);
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_allocate_preferred_size (ClutterActor *self,
|
||||
float x,
|
||||
float y);
|
||||
ClutterAllocationFlags flags);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_allocate_available_size (ClutterActor *self,
|
||||
gfloat x,
|
||||
gfloat y,
|
||||
gfloat available_width,
|
||||
gfloat available_height);
|
||||
gfloat available_height,
|
||||
ClutterAllocationFlags flags);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_allocate_align_fill (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
gdouble x_align,
|
||||
gdouble y_align,
|
||||
gboolean x_fill,
|
||||
gboolean y_fill);
|
||||
gboolean y_fill,
|
||||
ClutterAllocationFlags flags);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_allocation (ClutterActor *self,
|
||||
const ClutterActorBox *box);
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_allocation_box (ClutterActor *self,
|
||||
ClutterActorBox *box);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_allocation_vertices (ClutterActor *self,
|
||||
ClutterActor *ancestor,
|
||||
ClutterVertex verts[]);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_has_allocation (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_size (ClutterActor *self,
|
||||
@@ -403,10 +447,6 @@ void clutter_actor_set_position
|
||||
gfloat x,
|
||||
gfloat y);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_get_fixed_position (ClutterActor *self,
|
||||
float *x,
|
||||
float *y);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_position (ClutterActor *self,
|
||||
gfloat *x,
|
||||
gfloat *y);
|
||||
@@ -538,8 +578,7 @@ void clutter_actor_set_offscreen_redirect
|
||||
CLUTTER_EXPORT
|
||||
ClutterOffscreenRedirect clutter_actor_get_offscreen_redirect (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_should_pick (ClutterActor *self,
|
||||
ClutterPickContext *pick_context);
|
||||
gboolean clutter_actor_should_pick_paint (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_is_in_clone_paint (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
@@ -547,7 +586,8 @@ gboolean clutter_actor_get_paint_box
|
||||
ClutterActorBox *box);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
float clutter_actor_get_resource_scale (ClutterActor *self);
|
||||
gboolean clutter_actor_get_resource_scale (ClutterActor *self,
|
||||
gfloat *resource_scale);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_has_overlaps (ClutterActor *self);
|
||||
@@ -576,31 +616,22 @@ void clutter_actor_set_content_repeat
|
||||
ClutterContentRepeat repeat);
|
||||
CLUTTER_EXPORT
|
||||
ClutterContentRepeat clutter_actor_get_content_repeat (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_color_state (ClutterActor *self,
|
||||
ClutterColorState *color_state);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_unset_color_state (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterColorState * clutter_actor_get_color_state (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_content_box (ClutterActor *self,
|
||||
ClutterActorBox *box);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_background_color (ClutterActor *self,
|
||||
const CoglColor *color);
|
||||
const ClutterColor *color);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_background_color (ClutterActor *self,
|
||||
CoglColor *color);
|
||||
ClutterColor *color);
|
||||
CLUTTER_EXPORT
|
||||
const ClutterPaintVolume * clutter_actor_get_paint_volume (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
ClutterPaintVolume * clutter_actor_get_transformed_paint_volume (ClutterActor *self,
|
||||
const ClutterPaintVolume * clutter_actor_get_transformed_paint_volume (ClutterActor *self,
|
||||
ClutterActor *relative_to_ancestor);
|
||||
CLUTTER_EXPORT
|
||||
const ClutterPaintVolume * clutter_actor_get_default_paint_volume (ClutterActor *self);
|
||||
|
||||
/* Events */
|
||||
CLUTTER_EXPORT
|
||||
@@ -619,6 +650,14 @@ gboolean clutter_actor_event
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_has_pointer (ClutterActor *self);
|
||||
|
||||
/* Text */
|
||||
CLUTTER_EXPORT
|
||||
PangoContext * clutter_actor_get_pango_context (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
PangoContext * clutter_actor_create_pango_context (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
PangoLayout * clutter_actor_create_pango_layout (ClutterActor *self,
|
||||
const gchar *text);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_text_direction (ClutterActor *self,
|
||||
ClutterTextDirection text_dir);
|
||||
@@ -674,10 +713,6 @@ gboolean clutter_actor_contains
|
||||
ClutterActor *descendant);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor* clutter_actor_get_stage (ClutterActor *actor);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterContext * clutter_actor_get_context (ClutterActor *actor);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_child_below_sibling (ClutterActor *self,
|
||||
ClutterActor *child,
|
||||
@@ -756,21 +791,16 @@ void clutter_actor_get_translation
|
||||
gfloat *translate_z);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_transform (ClutterActor *self,
|
||||
const graphene_matrix_t *transform);
|
||||
const ClutterMatrix *transform);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_transform (ClutterActor *self,
|
||||
graphene_matrix_t *transform);
|
||||
ClutterMatrix *transform);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_child_transform (ClutterActor *self,
|
||||
const graphene_matrix_t *transform);
|
||||
const ClutterMatrix *transform);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_child_transform (ClutterActor *self,
|
||||
graphene_matrix_t *transform);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_transformed_extents (ClutterActor *self,
|
||||
graphene_rect_t *rect);
|
||||
|
||||
ClutterMatrix *transform);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_transformed_position (ClutterActor *self,
|
||||
gfloat *x,
|
||||
@@ -787,16 +817,16 @@ gboolean clutter_actor_transform_stage_point
|
||||
gfloat *y_out);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_abs_allocation_vertices (ClutterActor *self,
|
||||
graphene_point3d_t *verts);
|
||||
ClutterVertex verts[]);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_apply_transform_to_point (ClutterActor *self,
|
||||
const graphene_point3d_t *point,
|
||||
graphene_point3d_t *vertex);
|
||||
const ClutterVertex *point,
|
||||
ClutterVertex *vertex);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_apply_relative_transform_to_point (ClutterActor *self,
|
||||
ClutterActor *ancestor,
|
||||
const graphene_point3d_t *point,
|
||||
graphene_point3d_t *vertex);
|
||||
const ClutterVertex *point,
|
||||
ClutterVertex *vertex);
|
||||
|
||||
/* Implicit animations */
|
||||
CLUTTER_EXPORT
|
||||
@@ -840,11 +870,6 @@ void clutter_actor_set_opacity_override
|
||||
CLUTTER_EXPORT
|
||||
gint clutter_actor_get_opacity_override (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_inhibit_culling (ClutterActor *actor);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_uninhibit_culling (ClutterActor *actor);
|
||||
|
||||
/**
|
||||
* ClutterActorCreateChildFunc:
|
||||
* @item: (type GObject): the item in the model
|
||||
@@ -857,7 +882,9 @@ void clutter_actor_uninhibit_culling
|
||||
* of interest, using g_object_bind_property(). This way, when the @item
|
||||
* in the #GListModel changes, the #ClutterActor changes as well.
|
||||
*
|
||||
* Returns: (transfer full): The newly created child #ClutterActor4
|
||||
* Returns: (transfer full): The newly created child #ClutterActor
|
||||
*
|
||||
* Since: 1.24
|
||||
*/
|
||||
typedef ClutterActor * (* ClutterActorCreateChildFunc) (gpointer item,
|
||||
gpointer user_data);
|
||||
@@ -875,24 +902,6 @@ void clutter_actor_bind_model_with_properties
|
||||
const char *first_model_property,
|
||||
...);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_pick_box (ClutterActor *self,
|
||||
ClutterPickContext *pick_context,
|
||||
const ClutterActorBox *box);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GList * clutter_actor_peek_stage_views (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_invalidate_transform (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_invalidate_paint_volume (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_class_set_layout_manager_type (ClutterActorClass *actor_class,
|
||||
GType type);
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_actor_class_get_layout_manager_type (ClutterActorClass *actor_class);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ACTOR_H__ */
|
||||
|
||||
@@ -23,28 +23,34 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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
|
||||
* of the [class@Actor] to which it is applied to the size of another
|
||||
* [class@Actor] using an alignment factor
|
||||
* #ClutterAlignConstraint is available since Clutter 1.4
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter/clutter-align-constraint.h"
|
||||
#include "clutter-align-constraint.h"
|
||||
|
||||
#include "clutter/clutter-actor-meta-private.h"
|
||||
#include "clutter/clutter-actor-private.h"
|
||||
#include "clutter/clutter-constraint.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-enum-types.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#include "clutter-actor-meta-private.h"
|
||||
#include "clutter-actor-private.h"
|
||||
#include "clutter-constraint.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-enum-types.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define CLUTTER_ALIGN_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ALIGN_CONSTRAINT, ClutterAlignConstraintClass))
|
||||
#define CLUTTER_IS_ALIGN_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ALIGN_CONSTRAINT))
|
||||
#define CLUTTER_ALIGN_CONSTRAINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ALIGN_CONSTRAINT, ClutterAlignConstraintClass))
|
||||
|
||||
struct _ClutterAlignConstraint
|
||||
{
|
||||
ClutterConstraint parent_instance;
|
||||
@@ -52,17 +58,20 @@ struct _ClutterAlignConstraint
|
||||
ClutterActor *actor;
|
||||
ClutterActor *source;
|
||||
ClutterAlignAxis align_axis;
|
||||
graphene_point_t pivot;
|
||||
gfloat factor;
|
||||
};
|
||||
|
||||
struct _ClutterAlignConstraintClass
|
||||
{
|
||||
ClutterConstraintClass parent_class;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_SOURCE,
|
||||
PROP_ALIGN_AXIS,
|
||||
PROP_PIVOT_POINT,
|
||||
PROP_FACTOR,
|
||||
|
||||
PROP_LAST
|
||||
@@ -70,16 +79,18 @@ enum
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
G_DEFINE_FINAL_TYPE (ClutterAlignConstraint,
|
||||
clutter_align_constraint,
|
||||
CLUTTER_TYPE_CONSTRAINT);
|
||||
G_DEFINE_TYPE (ClutterAlignConstraint,
|
||||
clutter_align_constraint,
|
||||
CLUTTER_TYPE_CONSTRAINT);
|
||||
|
||||
static void
|
||||
source_queue_relayout (ClutterActor *actor,
|
||||
ClutterAlignConstraint *align)
|
||||
source_position_changed (ClutterActor *actor,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags,
|
||||
ClutterAlignConstraint *align)
|
||||
{
|
||||
if (align->actor != NULL)
|
||||
_clutter_actor_queue_only_relayout (align->actor);
|
||||
clutter_actor_queue_relayout (align->actor);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -124,41 +135,35 @@ clutter_align_constraint_update_allocation (ClutterConstraint *constraint,
|
||||
ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (constraint);
|
||||
gfloat source_width, source_height;
|
||||
gfloat actor_width, actor_height;
|
||||
gfloat offset_x_start, offset_y_start;
|
||||
gfloat pivot_x, pivot_y;
|
||||
gfloat source_x, source_y;
|
||||
|
||||
if (align->source == NULL)
|
||||
return;
|
||||
|
||||
clutter_actor_box_get_size (allocation, &actor_width, &actor_height);
|
||||
|
||||
clutter_actor_get_position (align->source, &source_x, &source_y);
|
||||
clutter_actor_get_size (align->source, &source_width, &source_height);
|
||||
|
||||
pivot_x = align->pivot.x == -1.f
|
||||
? align->factor
|
||||
: align->pivot.x;
|
||||
pivot_y = align->pivot.y == -1.f
|
||||
? align->factor
|
||||
: align->pivot.y;
|
||||
|
||||
offset_x_start = pivot_x * -actor_width;
|
||||
offset_y_start = pivot_y * -actor_height;
|
||||
|
||||
switch (align->align_axis)
|
||||
{
|
||||
case CLUTTER_ALIGN_X_AXIS:
|
||||
allocation->x1 += offset_x_start + (source_width * align->factor);
|
||||
allocation->x1 = ((source_width - actor_width) * align->factor)
|
||||
+ source_x;
|
||||
allocation->x2 = allocation->x1 + actor_width;
|
||||
break;
|
||||
|
||||
case CLUTTER_ALIGN_Y_AXIS:
|
||||
allocation->y1 += offset_y_start + (source_height * align->factor);
|
||||
allocation->y1 = ((source_height - actor_height) * align->factor)
|
||||
+ source_y;
|
||||
allocation->y2 = allocation->y1 + actor_height;
|
||||
break;
|
||||
|
||||
case CLUTTER_ALIGN_BOTH:
|
||||
allocation->x1 += offset_x_start + (source_width * align->factor);
|
||||
allocation->y1 += offset_y_start + (source_height * align->factor);
|
||||
allocation->x1 = ((source_width - actor_width) * align->factor)
|
||||
+ source_x;
|
||||
allocation->y1 = ((source_height - actor_height) * align->factor)
|
||||
+ source_y;
|
||||
allocation->x2 = allocation->x1 + actor_width;
|
||||
allocation->y2 = allocation->y1 + actor_height;
|
||||
break;
|
||||
@@ -182,7 +187,7 @@ clutter_align_constraint_dispose (GObject *gobject)
|
||||
G_CALLBACK (source_destroyed),
|
||||
align);
|
||||
g_signal_handlers_disconnect_by_func (align->source,
|
||||
G_CALLBACK (source_queue_relayout),
|
||||
G_CALLBACK (source_position_changed),
|
||||
align);
|
||||
align->source = NULL;
|
||||
}
|
||||
@@ -208,10 +213,6 @@ clutter_align_constraint_set_property (GObject *gobject,
|
||||
clutter_align_constraint_set_align_axis (align, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
case PROP_PIVOT_POINT:
|
||||
clutter_align_constraint_set_pivot_point (align, g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
case PROP_FACTOR:
|
||||
clutter_align_constraint_set_factor (align, g_value_get_float (value));
|
||||
break;
|
||||
@@ -240,16 +241,6 @@ clutter_align_constraint_get_property (GObject *gobject,
|
||||
g_value_set_enum (value, align->align_axis);
|
||||
break;
|
||||
|
||||
case PROP_PIVOT_POINT:
|
||||
{
|
||||
graphene_point_t point;
|
||||
|
||||
clutter_align_constraint_get_pivot_point (align, &point);
|
||||
|
||||
g_value_set_boxed (value, &point);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_FACTOR:
|
||||
g_value_set_float (value, align->factor);
|
||||
break;
|
||||
@@ -278,48 +269,30 @@ clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass)
|
||||
*
|
||||
* The #ClutterActor must not be a child or a grandchild of the actor
|
||||
* using the constraint.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
obj_props[PROP_SOURCE] =
|
||||
g_param_spec_object ("source", NULL, NULL,
|
||||
g_param_spec_object ("source",
|
||||
P_("Source"),
|
||||
P_("The source of the alignment"),
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT);
|
||||
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT);
|
||||
|
||||
/**
|
||||
* ClutterAlignConstraint:align-axis:
|
||||
*
|
||||
* The axis to be used to compute the alignment
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
obj_props[PROP_ALIGN_AXIS] =
|
||||
g_param_spec_enum ("align-axis", NULL, NULL,
|
||||
g_param_spec_enum ("align-axis",
|
||||
P_("Align Axis"),
|
||||
P_("The axis to align the position to"),
|
||||
CLUTTER_TYPE_ALIGN_AXIS,
|
||||
CLUTTER_ALIGN_X_AXIS,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT);
|
||||
|
||||
/**
|
||||
* ClutterAlignConstraint:pivot-point:
|
||||
*
|
||||
* The pivot point used by the constraint. The pivot point is the
|
||||
* point in the constraint actor around which the aligning is applied,
|
||||
* with (0, 0) being the top left corner of the actor and (1, 1) the
|
||||
* bottom right corner of the actor.
|
||||
*
|
||||
* For example, setting the pivot point to (0.5, 0.5) and using a factor
|
||||
* of 1 for both axes will align the actors horizontal and vertical
|
||||
* center point with the bottom right corner of the source actor.
|
||||
*
|
||||
* By default, the pivot point is set to (-1, -1), which means it's not
|
||||
* used and the constrained actor will be aligned to always stay inside
|
||||
* the source actor.
|
||||
*/
|
||||
obj_props[PROP_PIVOT_POINT] =
|
||||
g_param_spec_boxed ("pivot-point", NULL, NULL,
|
||||
GRAPHENE_TYPE_POINT,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT);
|
||||
|
||||
/**
|
||||
* ClutterAlignConstraint:factor:
|
||||
@@ -330,14 +303,16 @@ clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass)
|
||||
* with an align-axis value of %CLUTTER_ALIGN_X_AXIS, 0.0 means left and
|
||||
* 1.0 means right; with a value of %CLUTTER_ALIGN_Y_AXIS, 0.0 means top
|
||||
* and 1.0 means bottom.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
obj_props[PROP_FACTOR] =
|
||||
g_param_spec_float ("factor", NULL, NULL,
|
||||
g_param_spec_float ("factor",
|
||||
P_("Factor"),
|
||||
P_("The alignment factor, between 0.0 and 1.0"),
|
||||
0.0, 1.0,
|
||||
0.0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT);
|
||||
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT);
|
||||
|
||||
gobject_class->dispose = clutter_align_constraint_dispose;
|
||||
gobject_class->set_property = clutter_align_constraint_set_property;
|
||||
@@ -351,8 +326,6 @@ clutter_align_constraint_init (ClutterAlignConstraint *self)
|
||||
self->actor = NULL;
|
||||
self->source = NULL;
|
||||
self->align_axis = CLUTTER_ALIGN_X_AXIS;
|
||||
self->pivot.x = -1.f;
|
||||
self->pivot.y = -1.f;
|
||||
self->factor = 0.0f;
|
||||
}
|
||||
|
||||
@@ -368,6 +341,8 @@ clutter_align_constraint_init (ClutterAlignConstraint *self)
|
||||
* alignment @factor
|
||||
*
|
||||
* Return value: the newly created #ClutterAlignConstraint
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
ClutterConstraint *
|
||||
clutter_align_constraint_new (ClutterActor *source,
|
||||
@@ -389,6 +364,8 @@ clutter_align_constraint_new (ClutterActor *source,
|
||||
* @source: (allow-none): a #ClutterActor, or %NULL to unset the source
|
||||
*
|
||||
* Sets the source of the alignment constraint
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
clutter_align_constraint_set_source (ClutterAlignConstraint *align,
|
||||
@@ -426,15 +403,15 @@ clutter_align_constraint_set_source (ClutterAlignConstraint *align,
|
||||
G_CALLBACK (source_destroyed),
|
||||
align);
|
||||
g_signal_handlers_disconnect_by_func (old_source,
|
||||
G_CALLBACK (source_queue_relayout),
|
||||
G_CALLBACK (source_position_changed),
|
||||
align);
|
||||
}
|
||||
|
||||
align->source = source;
|
||||
if (align->source != NULL)
|
||||
{
|
||||
g_signal_connect (align->source, "queue-relayout",
|
||||
G_CALLBACK (source_queue_relayout),
|
||||
g_signal_connect (align->source, "allocation-changed",
|
||||
G_CALLBACK (source_position_changed),
|
||||
align);
|
||||
g_signal_connect (align->source, "destroy",
|
||||
G_CALLBACK (source_destroyed),
|
||||
@@ -455,6 +432,8 @@ clutter_align_constraint_set_source (ClutterAlignConstraint *align,
|
||||
*
|
||||
* Return value: (transfer none): the #ClutterActor used as the source
|
||||
* of the alignment
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_align_constraint_get_source (ClutterAlignConstraint *align)
|
||||
@@ -470,6 +449,8 @@ clutter_align_constraint_get_source (ClutterAlignConstraint *align)
|
||||
* @axis: the axis to which the alignment refers to
|
||||
*
|
||||
* Sets the axis to which the alignment refers to
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align,
|
||||
@@ -492,9 +473,11 @@ clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align,
|
||||
* clutter_align_constraint_get_align_axis:
|
||||
* @align: a #ClutterAlignConstraint
|
||||
*
|
||||
* Retrieves the value set using [method@Clutter.AlignConstraint.set_align_axis]
|
||||
* Retrieves the value set using clutter_align_constraint_set_align_axis()
|
||||
*
|
||||
* Return value: the alignment axis
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
ClutterAlignAxis
|
||||
clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align)
|
||||
@@ -505,60 +488,6 @@ clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align)
|
||||
return align->align_axis;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_set_pivot_point:
|
||||
* @align: a #ClutterAlignConstraint
|
||||
* @pivot_point: A #GraphenePoint
|
||||
*
|
||||
* Sets the pivot point used by the constraint, the pivot point is the
|
||||
* point in the constraint actor around which the aligning is applied,
|
||||
* with (0, 0) being the top left corner of the actor and (1, 1) the
|
||||
* bottom right corner of the actor.
|
||||
*
|
||||
* If -1 is used, the pivot point is unset and the constrained actor
|
||||
* will be aligned to always stay inside the source actor.
|
||||
*/
|
||||
void
|
||||
clutter_align_constraint_set_pivot_point (ClutterAlignConstraint *align,
|
||||
const graphene_point_t *pivot_point)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
|
||||
g_return_if_fail (pivot_point != NULL);
|
||||
g_return_if_fail (pivot_point->x == -1.f ||
|
||||
(pivot_point->x >= 0.f && pivot_point->x <= 1.f));
|
||||
g_return_if_fail (pivot_point->y == -1.f ||
|
||||
(pivot_point->y >= 0.f && pivot_point->y <= 1.f));
|
||||
|
||||
if (graphene_point_equal (&align->pivot, pivot_point))
|
||||
return;
|
||||
|
||||
align->pivot = *pivot_point;
|
||||
|
||||
if (align->actor != NULL)
|
||||
clutter_actor_queue_relayout (align->actor);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_PIVOT_POINT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_get_pivot_point
|
||||
* @align: a #ClutterAlignConstraint
|
||||
* @pivot_point: (out caller-allocates): return location for a #GraphenePoint
|
||||
*
|
||||
* Gets the pivot point used by the constraint set with
|
||||
* [method@Clutter.AlignConstraint.set_pivot_point]. If no custom pivot
|
||||
* point is set, -1 is set.
|
||||
*/
|
||||
void
|
||||
clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align,
|
||||
graphene_point_t *pivot_point)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
|
||||
g_return_if_fail (pivot_point != NULL);
|
||||
|
||||
*pivot_point = align->pivot;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_set_factor:
|
||||
* @align: a #ClutterAlignConstraint
|
||||
@@ -575,6 +504,8 @@ clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align,
|
||||
* meaning bottom, when #ClutterAlignConstraint:align-axis is set to
|
||||
* %CLUTTER_ALIGN_Y_AXIS). A value of 0.5 aligns in the middle in either
|
||||
* cases
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
clutter_align_constraint_set_factor (ClutterAlignConstraint *align,
|
||||
@@ -582,7 +513,7 @@ clutter_align_constraint_set_factor (ClutterAlignConstraint *align,
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
|
||||
|
||||
align->factor = CLAMP (factor, 0.0f, 1.0f);
|
||||
align->factor = CLAMP (factor, 0.0, 1.0);
|
||||
|
||||
if (align->actor != NULL)
|
||||
clutter_actor_queue_relayout (align->actor);
|
||||
@@ -594,9 +525,11 @@ clutter_align_constraint_set_factor (ClutterAlignConstraint *align,
|
||||
* clutter_align_constraint_get_factor:
|
||||
* @align: a #ClutterAlignConstraint
|
||||
*
|
||||
* Retrieves the factor set using [method@Clutter.AlignConstraint.set_factor]
|
||||
* Retrieves the factor set using clutter_align_constraint_set_factor()
|
||||
*
|
||||
* Return value: the alignment factor
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
gfloat
|
||||
clutter_align_constraint_get_factor (ClutterAlignConstraint *align)
|
||||
|
||||
@@ -22,21 +22,34 @@
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_ALIGN_CONSTRAINT_H__
|
||||
#define __CLUTTER_ALIGN_CONSTRAINT_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-constraint.h"
|
||||
#include <clutter/clutter-constraint.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_ALIGN_CONSTRAINT (clutter_align_constraint_get_type ())
|
||||
#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))
|
||||
|
||||
/**
|
||||
* ClutterAlignConstraint:
|
||||
*
|
||||
* #ClutterAlignConstraint is an opaque structure
|
||||
* whose members cannot be directly accesses
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
typedef struct _ClutterAlignConstraint ClutterAlignConstraint;
|
||||
typedef struct _ClutterAlignConstraintClass ClutterAlignConstraintClass;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_FINAL_TYPE (ClutterAlignConstraint, clutter_align_constraint,
|
||||
CLUTTER, ALIGN_CONSTRAINT, ClutterConstraint)
|
||||
GType clutter_align_constraint_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterConstraint *clutter_align_constraint_new (ClutterActor *source,
|
||||
@@ -54,15 +67,11 @@ void clutter_align_constraint_set_align_axis (ClutterAlignConstrai
|
||||
CLUTTER_EXPORT
|
||||
ClutterAlignAxis clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_align_constraint_set_pivot_point (ClutterAlignConstraint *align,
|
||||
const graphene_point_t *pivot_point);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align,
|
||||
graphene_point_t *pivot_point);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_align_constraint_set_factor (ClutterAlignConstraint *align,
|
||||
gfloat factor);
|
||||
CLUTTER_EXPORT
|
||||
gfloat clutter_align_constraint_get_factor (ClutterAlignConstraint *align);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ALIGN_CONSTRAINT_H__ */
|
||||
|
||||
@@ -23,25 +23,39 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterAnimatable:
|
||||
*
|
||||
* Interface for animatable classes
|
||||
* SECTION:clutter-animatable
|
||||
* @short_description: Interface for animatable classes
|
||||
*
|
||||
* #ClutterAnimatable is an interface that allows a [class@GObject.Object] class
|
||||
* to control how an actor will animate a property.
|
||||
* #ClutterAnimatable is an interface that allows a #GObject class
|
||||
* to control how a #ClutterAnimation will animate a property.
|
||||
*
|
||||
* 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
|
||||
* 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 "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter/clutter-animatable.h"
|
||||
#include "clutter/clutter-interval.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#include "clutter-animatable.h"
|
||||
#include "clutter-interval.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
#include "deprecated/clutter-animatable.h"
|
||||
#include "deprecated/clutter-animation.h"
|
||||
|
||||
G_DEFINE_INTERFACE (ClutterAnimatable, clutter_animatable, G_TYPE_OBJECT);
|
||||
|
||||
@@ -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:
|
||||
* @animatable: a #ClutterAnimatable
|
||||
* @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
|
||||
* or %NULL
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
GParamSpec *
|
||||
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
|
||||
*
|
||||
* Retrieves the current state of @property_name and sets @value with it
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
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
|
||||
*
|
||||
* Sets the current state of @property_name to @value
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
clutter_animatable_set_final_state (ClutterAnimatable *animatable,
|
||||
@@ -149,10 +243,14 @@ clutter_animatable_set_final_state (ClutterAnimatable *animatable,
|
||||
* value, and store the result inside @value.
|
||||
*
|
||||
* This function should be used for every property animation
|
||||
* involving `ClutterAnimatable`s.
|
||||
* involving #ClutterAnimatable<!-- -->s.
|
||||
*
|
||||
* This function replaces clutter_animatable_animate_property().
|
||||
*
|
||||
* Return value: %TRUE if the interpolation was successful,
|
||||
* and %FALSE otherwise
|
||||
*
|
||||
* Since: 1.8
|
||||
*/
|
||||
gboolean
|
||||
clutter_animatable_interpolate_value (ClutterAnimatable *animatable,
|
||||
@@ -183,25 +281,3 @@ clutter_animatable_interpolate_value (ClutterAnimatable *animatable,
|
||||
else
|
||||
return clutter_interval_compute_value (interval, progress, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_animatable_get_actor:
|
||||
* @animatable: a #ClutterAnimatable
|
||||
*
|
||||
* Get animated actor.
|
||||
*
|
||||
* Return value: (transfer none): a #ClutterActor
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_animatable_get_actor (ClutterAnimatable *animatable)
|
||||
{
|
||||
ClutterAnimatableInterface *iface;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), NULL);
|
||||
|
||||
iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable);
|
||||
|
||||
g_return_val_if_fail (iface->get_actor, NULL);
|
||||
|
||||
return iface->get_actor (animatable);
|
||||
}
|
||||
|
||||
@@ -22,13 +22,14 @@
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_ANIMATABLE_H__
|
||||
#define __CLUTTER_ANIMATABLE_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
#include <clutter/clutter-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -41,6 +42,8 @@ G_DECLARE_INTERFACE (ClutterAnimatable, clutter_animatable,
|
||||
|
||||
/**
|
||||
* ClutterAnimatableInterface:
|
||||
* @animate_property: virtual function for custom interpolation of a
|
||||
* property. This virtual function is deprecated
|
||||
* @find_property: virtual function for retrieving the #GParamSpec of
|
||||
* an animatable property
|
||||
* @get_initial_state: virtual function for retrieving the initial
|
||||
@@ -49,7 +52,11 @@ G_DECLARE_INTERFACE (ClutterAnimatable, clutter_animatable,
|
||||
* animatable property
|
||||
* @interpolate_value: virtual function for interpolating the progress
|
||||
* of a property
|
||||
* @get_actor: virtual function for getting associated actor
|
||||
*
|
||||
* Base interface for #GObject<!-- -->s that can be animated by a
|
||||
* a #ClutterAnimation.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
struct _ClutterAnimatableInterface
|
||||
{
|
||||
@@ -57,6 +64,13 @@ struct _ClutterAnimatableInterface
|
||||
GTypeInterface parent_iface;
|
||||
|
||||
/*< public >*/
|
||||
gboolean (* animate_property) (ClutterAnimatable *animatable,
|
||||
ClutterAnimation *animation,
|
||||
const gchar *property_name,
|
||||
const GValue *initial_value,
|
||||
const GValue *final_value,
|
||||
gdouble progress,
|
||||
GValue *value);
|
||||
GParamSpec *(* find_property) (ClutterAnimatable *animatable,
|
||||
const gchar *property_name);
|
||||
void (* get_initial_state) (ClutterAnimatable *animatable,
|
||||
@@ -70,7 +84,6 @@ struct _ClutterAnimatableInterface
|
||||
ClutterInterval *interval,
|
||||
gdouble progress,
|
||||
GValue *value);
|
||||
ClutterActor * (* get_actor) (ClutterAnimatable *animatable);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
@@ -91,7 +104,6 @@ gboolean clutter_animatable_interpolate_value (ClutterAnimatable *animatable,
|
||||
gdouble progress,
|
||||
GValue *value);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_animatable_get_actor (ClutterAnimatable *animatable);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ANIMATABLE_H__ */
|
||||
|
||||
104
clutter/clutter/clutter-autocleanups.h
Normal file
104
clutter/clutter/clutter-autocleanups.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright 2015 Emmanuele Bassi
|
||||
*
|
||||
* 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_AUTO_CLEANUPS_H__
|
||||
#define __CLUTTER_AUTO_CLEANUPS_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GI_SCANNER__
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAction, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActor, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorMeta, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAlignConstraint, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackend, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBindConstraint, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBindingPool, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBinLayout, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBlurEffect, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBoxLayout, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBrightnessContrastEffect, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterCanvas, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterChildMeta, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterClickAction, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterClone, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColorizeEffect, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterConstraint, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterContainer, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDeformEffect, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDesaturateEffect, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDeviceManager, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDragAction, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDropAction, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterEffect, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFixedLayout, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFlowLayout, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterGestureAction, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterGridLayout, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterImage, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterInputDevice, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterInterval, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterKeyframeTransition, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterLayoutManager, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterLayoutMeta, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterOffscreenEffect, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPageTurnEffect, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPanAction, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPathConstraint, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPath, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPropertyTransition, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterRotateAction, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterScriptable, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterScript, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterScrollActor, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterSettings, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterShaderEffect, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterSnapConstraint, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterStage, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterSwipeAction, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterTapAction, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterTextBuffer, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterText, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterTimeline, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterTransitionGroup, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterTransition, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterZoomAction, g_object_unref)
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorBox, clutter_actor_box_free)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColor, clutter_color_free)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMargin, clutter_margin_free)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMatrix, clutter_matrix_free)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintNode, clutter_paint_node_unref)
|
||||
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 (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 /* __CLUTTER_AUTO_CLEANUPS_H__ */
|
||||
@@ -19,15 +19,15 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_BACKEND_PRIVATE_H__
|
||||
#define __CLUTTER_BACKEND_PRIVATE_H__
|
||||
|
||||
#ifdef HAVE_FONTS
|
||||
#include <cairo.h>
|
||||
#endif
|
||||
#include <clutter/clutter-backend.h>
|
||||
#include <clutter/clutter-device-manager.h>
|
||||
#include <clutter/clutter-keymap.h>
|
||||
#include <clutter/clutter-stage-window.h>
|
||||
|
||||
#include "clutter/clutter-backend.h"
|
||||
#include "clutter/clutter-seat.h"
|
||||
#include "clutter/clutter-stage-window.h"
|
||||
#include "clutter-event-translator.h"
|
||||
|
||||
#define CLUTTER_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BACKEND, ClutterBackendClass))
|
||||
#define CLUTTER_IS_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BACKEND))
|
||||
@@ -42,8 +42,6 @@ struct _ClutterBackend
|
||||
/*< private >*/
|
||||
GObject parent_instance;
|
||||
|
||||
ClutterContext *context;
|
||||
|
||||
CoglRenderer *cogl_renderer;
|
||||
CoglDisplay *cogl_display;
|
||||
CoglContext *cogl_context;
|
||||
@@ -51,15 +49,20 @@ struct _ClutterBackend
|
||||
|
||||
CoglOnscreen *dummy_onscreen;
|
||||
|
||||
#ifdef HAVE_FONTS
|
||||
ClutterDeviceManager *device_manager;
|
||||
|
||||
cairo_font_options_t *font_options;
|
||||
#endif
|
||||
|
||||
float fallback_resource_scale;
|
||||
gchar *font_name;
|
||||
|
||||
ClutterStageWindow *stage_window;
|
||||
gfloat units_per_em;
|
||||
gint32 units_serial;
|
||||
|
||||
GList *event_translators;
|
||||
|
||||
ClutterInputMethod *input_method;
|
||||
|
||||
ClutterKeymap *keymap;
|
||||
};
|
||||
|
||||
struct _ClutterBackendClass
|
||||
@@ -68,40 +71,95 @@ struct _ClutterBackendClass
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* vfuncs */
|
||||
gboolean (* pre_parse) (ClutterBackend *backend,
|
||||
GError **error);
|
||||
gboolean (* post_parse) (ClutterBackend *backend,
|
||||
GError **error);
|
||||
ClutterStageWindow * (* create_stage) (ClutterBackend *backend,
|
||||
ClutterStage *wrapper,
|
||||
GError **error);
|
||||
void (* init_events) (ClutterBackend *backend);
|
||||
void (* init_features) (ClutterBackend *backend);
|
||||
void (* add_options) (ClutterBackend *backend,
|
||||
GOptionGroup *group);
|
||||
ClutterFeatureFlags (* get_features) (ClutterBackend *backend);
|
||||
CoglRenderer * (* get_renderer) (ClutterBackend *backend,
|
||||
GError **error);
|
||||
CoglDisplay * (* get_display) (ClutterBackend *backend,
|
||||
CoglRenderer *renderer,
|
||||
CoglSwapChain *swap_chain,
|
||||
GError **error);
|
||||
gboolean (* create_context) (ClutterBackend *backend,
|
||||
GError **error);
|
||||
ClutterDeviceManager *(* get_device_manager) (ClutterBackend *backend);
|
||||
|
||||
ClutterSeat * (* get_default_seat) (ClutterBackend *backend);
|
||||
void (* copy_event_data) (ClutterBackend *backend,
|
||||
const ClutterEvent *src,
|
||||
ClutterEvent *dest);
|
||||
void (* free_event_data) (ClutterBackend *backend,
|
||||
ClutterEvent *event);
|
||||
|
||||
gboolean (* is_display_server) (ClutterBackend *backend);
|
||||
gboolean (* translate_event) (ClutterBackend *backend,
|
||||
gpointer native,
|
||||
ClutterEvent *event);
|
||||
|
||||
PangoDirection (* get_keymap_direction) (ClutterBackend *backend);
|
||||
|
||||
void (* bell_notify) (ClutterBackend *backend);
|
||||
|
||||
ClutterKeymap * (* get_keymap) (ClutterBackend *backend);
|
||||
|
||||
/* signals */
|
||||
void (* resolution_changed) (ClutterBackend *backend);
|
||||
void (* font_changed) (ClutterBackend *backend);
|
||||
void (* settings_changed) (ClutterBackend *backend);
|
||||
};
|
||||
|
||||
ClutterBackend * _clutter_create_backend (void);
|
||||
|
||||
ClutterStageWindow * _clutter_backend_create_stage (ClutterBackend *backend,
|
||||
ClutterStage *wrapper,
|
||||
GError **error);
|
||||
gboolean _clutter_backend_create_context (ClutterBackend *backend,
|
||||
GError **error);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterStageWindow * clutter_backend_get_stage_window (ClutterBackend *backend);
|
||||
void _clutter_backend_add_options (ClutterBackend *backend,
|
||||
GOptionGroup *group);
|
||||
gboolean _clutter_backend_pre_parse (ClutterBackend *backend,
|
||||
GError **error);
|
||||
gboolean _clutter_backend_post_parse (ClutterBackend *backend,
|
||||
GError **error);
|
||||
|
||||
void _clutter_backend_init_events (ClutterBackend *backend);
|
||||
void _clutter_backend_copy_event_data (ClutterBackend *backend,
|
||||
const ClutterEvent *src,
|
||||
ClutterEvent *dest);
|
||||
void _clutter_backend_free_event_data (ClutterBackend *backend,
|
||||
ClutterEvent *event);
|
||||
gboolean _clutter_backend_translate_event (ClutterBackend *backend,
|
||||
gpointer native,
|
||||
ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_backend_set_fallback_resource_scale (ClutterBackend *backend,
|
||||
float fallback_resource_scale);
|
||||
void _clutter_backend_add_event_translator (ClutterBackend *backend,
|
||||
ClutterEventTranslator *translator);
|
||||
|
||||
float clutter_backend_get_fallback_resource_scale (ClutterBackend *backend);
|
||||
void _clutter_backend_remove_event_translator (ClutterBackend *backend,
|
||||
ClutterEventTranslator *translator);
|
||||
|
||||
gboolean clutter_backend_is_display_server (ClutterBackend *backend);
|
||||
ClutterFeatureFlags _clutter_backend_get_features (ClutterBackend *backend);
|
||||
|
||||
gfloat _clutter_backend_get_units_per_em (ClutterBackend *backend,
|
||||
PangoFontDescription *font_desc);
|
||||
gint32 _clutter_backend_get_units_serial (ClutterBackend *backend);
|
||||
|
||||
PangoDirection _clutter_backend_get_keymap_direction (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_backend_destroy (ClutterBackend *backend);
|
||||
void _clutter_backend_reset_cogl_framebuffer (ClutterBackend *backend);
|
||||
|
||||
void clutter_set_allowed_drivers (const char *drivers);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_BACKEND_PRIVATE_H__ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,17 +21,21 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_BACKEND_H__
|
||||
#define __CLUTTER_BACKEND_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
#include <cairo.h>
|
||||
#include <pango/pango.h>
|
||||
|
||||
#include "clutter/clutter-keymap.h"
|
||||
#include "clutter/clutter-types.h"
|
||||
#include "clutter/clutter-seat.h"
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include <clutter/clutter-config.h>
|
||||
#include <clutter/clutter-keymap.h>
|
||||
#include <clutter/clutter-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -39,6 +43,14 @@ G_BEGIN_DECLS
|
||||
#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))
|
||||
|
||||
/**
|
||||
* ClutterBackend:
|
||||
*
|
||||
* #ClutterBackend is an opaque structure whose
|
||||
* members cannot be directly accessed.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
typedef struct _ClutterBackend ClutterBackend;
|
||||
typedef struct _ClutterBackendClass ClutterBackendClass;
|
||||
|
||||
@@ -51,9 +63,18 @@ ClutterBackend * clutter_get_default_backend (void);
|
||||
CLUTTER_EXPORT
|
||||
gdouble clutter_backend_get_resolution (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_backend_set_font_options (ClutterBackend *backend,
|
||||
const cairo_font_options_t *options);
|
||||
CLUTTER_EXPORT
|
||||
const cairo_font_options_t * clutter_backend_get_font_options (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
CoglContext * clutter_backend_get_cogl_context (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_backend_bell_notify (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterInputMethod * clutter_backend_get_input_method (ClutterBackend *backend);
|
||||
|
||||
@@ -61,8 +82,8 @@ CLUTTER_EXPORT
|
||||
void clutter_backend_set_input_method (ClutterBackend *backend,
|
||||
ClutterInputMethod *method);
|
||||
CLUTTER_EXPORT
|
||||
ClutterSeat * clutter_backend_get_default_seat (ClutterBackend *backend);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackend, g_object_unref)
|
||||
ClutterKeymap * clutter_backend_get_keymap (ClutterBackend *backend);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_BACKEND_H__ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
514
clutter/clutter/clutter-bezier.c
Normal file
514
clutter/clutter/clutter-bezier.c
Normal file
@@ -0,0 +1,514 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Tomas Frydrych <tf@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2007 OpenedHand
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
#include "clutter-bezier.h"
|
||||
#include "clutter-debug.h"
|
||||
|
||||
/*
|
||||
* We have some experimental code here to allow for constant velocity
|
||||
* movement of actors along the bezier path, this macro enables it.
|
||||
*/
|
||||
#undef CBZ_L2T_INTERPOLATION
|
||||
|
||||
/****************************************************************************
|
||||
* ClutterBezier -- represenation of a cubic bezier curve *
|
||||
* (private; a building block for the public bspline object) *
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* The t parameter of the bezier is from interval <0,1>, so we can use
|
||||
* 14.18 format and special multiplication functions that preserve
|
||||
* more of the least significant bits but would overflow if the value
|
||||
* is > 1
|
||||
*/
|
||||
#define CBZ_T_Q 18
|
||||
#define CBZ_T_ONE (1 << CBZ_T_Q)
|
||||
#define CBZ_T_MUL(x,y) ((((x) >> 3) * ((y) >> 3)) >> 12)
|
||||
#define CBZ_T_POW2(x) CBZ_T_MUL (x, x)
|
||||
#define CBZ_T_POW3(x) CBZ_T_MUL (CBZ_T_POW2 (x), x)
|
||||
#define CBZ_T_DIV(x,y) ((((x) << 9)/(y)) << 9)
|
||||
|
||||
/*
|
||||
* Constants for sampling of the bezier
|
||||
*/
|
||||
#define CBZ_T_SAMPLES 128
|
||||
#define CBZ_T_STEP (CBZ_T_ONE / CBZ_T_SAMPLES)
|
||||
#define CBZ_L_STEP (CBZ_T_ONE / CBZ_T_SAMPLES)
|
||||
|
||||
#define FIXED_BITS (32)
|
||||
#define FIXED_Q (FIXED_BITS - 16)
|
||||
#define FIXED_FROM_INT(x) ((x) << FIXED_Q)
|
||||
|
||||
typedef gint32 _FixedT;
|
||||
|
||||
/*
|
||||
* This is a private type representing a single cubic bezier
|
||||
*/
|
||||
struct _ClutterBezier
|
||||
{
|
||||
/*
|
||||
* bezier coefficients -- these are calculated using multiplication and
|
||||
* addition from integer input, so these are also integers
|
||||
*/
|
||||
gint ax;
|
||||
gint bx;
|
||||
gint cx;
|
||||
gint dx;
|
||||
|
||||
gint ay;
|
||||
gint by;
|
||||
gint cy;
|
||||
gint dy;
|
||||
|
||||
/* length of the bezier */
|
||||
guint length;
|
||||
|
||||
#ifdef CBZ_L2T_INTERPOLATION
|
||||
/*
|
||||
* coefficients for the L -> t bezier; these are calculated from fixed
|
||||
* point input, and more specifically numbers that have been normalised
|
||||
* to fit <0,1>, so these are also fixed point, and we can used the
|
||||
* _FixedT type here.
|
||||
*/
|
||||
_FixedT La;
|
||||
_FixedT Lb;
|
||||
_FixedT Lc;
|
||||
/* _FixedT Ld; == 0 */
|
||||
#endif
|
||||
};
|
||||
|
||||
ClutterBezier *
|
||||
_clutter_bezier_new (void)
|
||||
{
|
||||
return g_slice_new0 (ClutterBezier);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_bezier_free (ClutterBezier * b)
|
||||
{
|
||||
if (G_LIKELY (b))
|
||||
{
|
||||
g_slice_free (ClutterBezier, b);
|
||||
}
|
||||
}
|
||||
|
||||
ClutterBezier *
|
||||
_clutter_bezier_clone_and_move (const ClutterBezier *b, gint x, gint y)
|
||||
{
|
||||
ClutterBezier * b2 = _clutter_bezier_new ();
|
||||
memcpy (b2, b, sizeof (ClutterBezier));
|
||||
|
||||
b2->dx += x;
|
||||
b2->dy += y;
|
||||
|
||||
return b2;
|
||||
}
|
||||
|
||||
#ifdef CBZ_L2T_INTERPOLATION
|
||||
/*
|
||||
* L is relative advance along the bezier curve from interval <0,1>
|
||||
*/
|
||||
static _FixedT
|
||||
_clutter_bezier_L2t (const ClutterBezier *b, _FixedT L)
|
||||
{
|
||||
_FixedT t = CBZ_T_MUL (b->La, CBZ_T_POW3(L))
|
||||
+ CBZ_T_MUL (b->Lb, CBZ_T_POW2(L))
|
||||
+ CBZ_T_MUL (b->Lc, L);
|
||||
|
||||
if (t > CBZ_T_ONE)
|
||||
t = CBZ_T_ONE;
|
||||
else if (t < 0)
|
||||
t = 0;
|
||||
|
||||
return t;
|
||||
}
|
||||
#endif
|
||||
|
||||
static gint
|
||||
_clutter_bezier_t2x (const ClutterBezier * b, _FixedT t)
|
||||
{
|
||||
/*
|
||||
* NB -- the int coefficients can be at most 8192 for the multiplication
|
||||
* to work in this fashion due to the limits of the 14.18 fixed.
|
||||
*/
|
||||
return ((b->ax*CBZ_T_POW3(t) + b->bx*CBZ_T_POW2(t) + b->cx*t) >> CBZ_T_Q)
|
||||
+ b->dx;
|
||||
}
|
||||
|
||||
static gint
|
||||
_clutter_bezier_t2y (const ClutterBezier * b, _FixedT t)
|
||||
{
|
||||
/*
|
||||
* NB -- the int coefficients can be at most 8192 for the multiplication
|
||||
* to work in this fashion due to the limits of the 14.18 fixed.
|
||||
*/
|
||||
return ((b->ay*CBZ_T_POW3(t) + b->by*CBZ_T_POW2(t) + b->cy*t) >> CBZ_T_Q)
|
||||
+ b->dy;
|
||||
}
|
||||
|
||||
/*
|
||||
* Advances along the bezier to relative length L and returns the coordinances
|
||||
* in knot
|
||||
*/
|
||||
void
|
||||
_clutter_bezier_advance (const ClutterBezier *b, gint L, ClutterKnot * knot)
|
||||
{
|
||||
#ifdef CBZ_L2T_INTERPOLATION
|
||||
_FixedT t = clutter_bezier_L2t (b, L);
|
||||
#else
|
||||
_FixedT t = L;
|
||||
#endif
|
||||
|
||||
knot->x = _clutter_bezier_t2x (b, t);
|
||||
knot->y = _clutter_bezier_t2y (b, t);
|
||||
|
||||
CLUTTER_NOTE (MISC, "advancing to relative pt %f: t %f, {%d,%d}",
|
||||
(double) L / (double) CBZ_T_ONE,
|
||||
(double) t / (double) CBZ_T_ONE,
|
||||
knot->x, knot->y);
|
||||
}
|
||||
|
||||
static int
|
||||
sqrti (int number)
|
||||
{
|
||||
#if defined __SSE2__
|
||||
/* The GCC built-in with SSE2 (sqrtsd) is up to twice as fast as
|
||||
* the pure integer code below. It is also more accurate.
|
||||
*/
|
||||
return __builtin_sqrt (number);
|
||||
#else
|
||||
/* This is a fixed point implementation of the Quake III sqrt algorithm,
|
||||
* described, for example, at
|
||||
* http://www.codemaestro.com/reviews/review00000105.html
|
||||
*
|
||||
* While the original QIII is extremely fast, the use of floating division
|
||||
* and multiplication makes it perform very on arm processors without FPU.
|
||||
*
|
||||
* The key to successfully replacing the floating point operations with
|
||||
* fixed point is in the choice of the fixed point format. The QIII
|
||||
* algorithm does not calculate the square root, but its reciprocal ('y'
|
||||
* below), which is only at the end turned to the inverse value. In order
|
||||
* for the algorithm to produce satisfactory results, the reciprocal value
|
||||
* must be represented with sufficient precission; the 16.16 we use
|
||||
* elsewhere in clutter is not good enough, and 10.22 is used instead.
|
||||
*/
|
||||
_FixedT x;
|
||||
uint32_t y_1; /* 10.22 fixed point */
|
||||
uint32_t f = 0x600000; /* '1.5' as 10.22 fixed */
|
||||
|
||||
union
|
||||
{
|
||||
float f;
|
||||
uint32_t i;
|
||||
} flt, flt2;
|
||||
|
||||
flt.f = number;
|
||||
|
||||
x = FIXED_FROM_INT (number) / 2;
|
||||
|
||||
/* The QIII initial estimate */
|
||||
flt.i = 0x5f3759df - ( flt.i >> 1 );
|
||||
|
||||
/* Now, we convert the float to 10.22 fixed. We exploit the mechanism
|
||||
* described at http://www.d6.com/users/checker/pdfs/gdmfp.pdf.
|
||||
*
|
||||
* We want 22 bit fraction; a single precission float uses 23 bit
|
||||
* mantisa, so we only need to add 2^(23-22) (no need for the 1.5
|
||||
* multiplier as we are only dealing with positive numbers).
|
||||
*
|
||||
* Note: we have to use two separate variables here -- for some reason,
|
||||
* if we try to use just the flt variable, gcc on ARM optimises the whole
|
||||
* addition out, and it all goes pear shape, since without it, the bits
|
||||
* in the float will not be correctly aligned.
|
||||
*/
|
||||
flt2.f = flt.f + 2.0;
|
||||
flt2.i &= 0x7FFFFF;
|
||||
|
||||
/* Now we correct the estimate */
|
||||
y_1 = (flt2.i >> 11) * (flt2.i >> 11);
|
||||
y_1 = (y_1 >> 8) * (x >> 8);
|
||||
|
||||
y_1 = f - y_1;
|
||||
flt2.i = (flt2.i >> 11) * (y_1 >> 11);
|
||||
|
||||
/* If the original argument is less than 342, we do another
|
||||
* iteration to improve precission (for arguments >= 342, the single
|
||||
* iteration produces generally better results).
|
||||
*/
|
||||
if (x < 171)
|
||||
{
|
||||
y_1 = (flt2.i >> 11) * (flt2.i >> 11);
|
||||
y_1 = (y_1 >> 8) * (x >> 8);
|
||||
|
||||
y_1 = f - y_1;
|
||||
flt2.i = (flt2.i >> 11) * (y_1 >> 11);
|
||||
}
|
||||
|
||||
/* Invert, round and convert from 10.22 to an integer
|
||||
* 0x1e3c68 is a magical rounding constant that produces slightly
|
||||
* better results than 0x200000.
|
||||
*/
|
||||
return (number * flt2.i + 0x1e3c68) >> 22;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_bezier_init (ClutterBezier *b,
|
||||
gint x_0, gint y_0,
|
||||
gint x_1, gint y_1,
|
||||
gint x_2, gint y_2,
|
||||
gint x_3, gint y_3)
|
||||
{
|
||||
_FixedT t;
|
||||
int i;
|
||||
int xp = x_0;
|
||||
int yp = y_0;
|
||||
_FixedT length [CBZ_T_SAMPLES + 1];
|
||||
|
||||
#ifdef CBZ_L2T_INTERPOLATION
|
||||
int j, k;
|
||||
_FixedT L;
|
||||
_FixedT t_equalized [CBZ_T_SAMPLES + 1];
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
g_debug ("Initializing bezier at {{%d,%d},{%d,%d},{%d,%d},{%d,%d}}",
|
||||
x0, y0, x1, y1, x2, y2, x3, y3);
|
||||
#endif
|
||||
|
||||
b->dx = x_0;
|
||||
b->dy = y_0;
|
||||
|
||||
b->cx = 3 * (x_1 - x_0);
|
||||
b->cy = 3 * (y_1 - y_0);
|
||||
|
||||
b->bx = 3 * (x_2 - x_1) - b->cx;
|
||||
b->by = 3 * (y_2 - y_1) - b->cy;
|
||||
|
||||
b->ax = x_3 - 3 * x_2 + 3 * x_1 - x_0;
|
||||
b->ay = y_3 - 3 * y_2 + 3 * y_1 - y_0;
|
||||
|
||||
#if 0
|
||||
g_debug ("Cooeficients {{%d,%d},{%d,%d},{%d,%d},{%d,%d}}",
|
||||
b->ax, b->ay, b->bx, b->by, b->cx, b->cy, b->dx, b->dy);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Because of the way we do the multiplication in bezeir_t2x,y
|
||||
* these coefficients need to be at most 0x1fff; this should be the case,
|
||||
* I think, but have added this warning to catch any problems -- if it
|
||||
* triggers, we need to change those two functions a bit.
|
||||
*/
|
||||
if (b->ax > 0x1fff || b->bx > 0x1fff || b->cx > 0x1fff)
|
||||
g_warning ("Calculated coefficients will result in multiplication "
|
||||
"overflow in clutter_bezier_t2x and clutter_bezier_t2y.");
|
||||
|
||||
/*
|
||||
* Sample the bezier with CBZ_T_SAMPLES and calculate length at
|
||||
* each point.
|
||||
*
|
||||
* We are working with integers here, so we use the fast sqrti function.
|
||||
*/
|
||||
length[0] = 0;
|
||||
|
||||
for (t = CBZ_T_STEP, i = 1; i <= CBZ_T_SAMPLES; ++i, t += CBZ_T_STEP)
|
||||
{
|
||||
int x = _clutter_bezier_t2x (b, t);
|
||||
int y = _clutter_bezier_t2y (b, t);
|
||||
|
||||
guint l = sqrti ((y - yp)*(y - yp) + (x - xp)*(x - xp));
|
||||
|
||||
l += length[i-1];
|
||||
|
||||
length[i] = l;
|
||||
|
||||
xp = x;
|
||||
yp = y;
|
||||
}
|
||||
|
||||
b->length = length[CBZ_T_SAMPLES];
|
||||
|
||||
#if 0
|
||||
g_debug ("length %d", b->length);
|
||||
#endif
|
||||
|
||||
#ifdef CBZ_L2T_INTERPOLATION
|
||||
/*
|
||||
* Now normalize the length values, converting them into _FixedT
|
||||
*/
|
||||
for (i = 0; i <= CBZ_T_SAMPLES; ++i)
|
||||
{
|
||||
length[i] = (length[i] << CBZ_T_Q) / b->length;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now generate a L -> t table such that the L will equidistant
|
||||
* over <0,1>
|
||||
*/
|
||||
t_equalized[0] = 0;
|
||||
|
||||
for (i = 1, j = 1, L = CBZ_L_STEP; i < CBZ_T_SAMPLES; ++i, L += CBZ_L_STEP)
|
||||
{
|
||||
_FixedT l1, l2;
|
||||
_FixedT d1, d2, d;
|
||||
_FixedT t1, t2;
|
||||
|
||||
/* find the band for our L */
|
||||
for (k = j; k < CBZ_T_SAMPLES; ++k)
|
||||
{
|
||||
if (L < length[k])
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we know that L is from (length[k-1],length[k]>
|
||||
* We remember k-1 in order not to have to iterate over the
|
||||
* whole length array in the next iteration of the main loop
|
||||
*/
|
||||
j = k - 1;
|
||||
|
||||
/*
|
||||
* Now interpolate equlised t as a weighted average
|
||||
*/
|
||||
l1 = length[k-1];
|
||||
l2 = length[k];
|
||||
d1 = l2 - L;
|
||||
d2 = L - l1;
|
||||
d = l2 - l1;
|
||||
t1 = (k - 1) * CBZ_T_STEP;
|
||||
t2 = k * CBZ_T_STEP;
|
||||
|
||||
t_equalized[i] = (t1*d1 + t2*d2)/d;
|
||||
|
||||
if (t_equalized[i] < t_equalized[i-1])
|
||||
g_debug ("wrong t: L %f, l1 %f, l2 %f, t1 %f, t2 %f",
|
||||
(double) (L)/(double)CBZ_T_ONE,
|
||||
(double) (l1)/(double)CBZ_T_ONE,
|
||||
(double) (l2)/(double)CBZ_T_ONE,
|
||||
(double) (t1)/(double)CBZ_T_ONE,
|
||||
(double) (t2)/(double)CBZ_T_ONE);
|
||||
|
||||
}
|
||||
|
||||
t_equalized[CBZ_T_SAMPLES] = CBZ_T_ONE;
|
||||
|
||||
/* We now fit a bezier -- at this stage, do a single fit through our values
|
||||
* at 0, 1/3, 2/3 and 1
|
||||
*
|
||||
* FIXME -- do we need to use a better fitting approach to choose the best
|
||||
* beziere. The actual curve we acquire this way is not too bad shapwise,
|
||||
* but (probably due to rounding errors) the resulting curve no longer
|
||||
* satisfies the necessary condition that for L2 > L1, t2 > t1, which
|
||||
* causes oscilation.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* These are the control points we use to calculate the curve coefficients
|
||||
* for bezier t(L); these are not needed directly, but are implied in the
|
||||
* calculations below.
|
||||
*
|
||||
* (p0 is 0,0, and p3 is 1,1)
|
||||
*/
|
||||
p1 = (18 * t_equalized[CBZ_T_SAMPLES/3] -
|
||||
9 * t_equalized[2*CBZ_T_SAMPLES/3] +
|
||||
2 << CBZ_T_Q) / 6;
|
||||
|
||||
p2 = (18 * t_equalized[2*CBZ_T_SAMPLES/3] -
|
||||
9 * t_equalized[CBZ_T_SAMPLES/3] -
|
||||
(5 << CBZ_T_Q)) / 6;
|
||||
#endif
|
||||
|
||||
b->Lc = (18 * t_equalized[CBZ_T_SAMPLES/3] -
|
||||
9 * t_equalized[2*CBZ_T_SAMPLES/3] +
|
||||
(2 << CBZ_T_Q)) >> 1;
|
||||
|
||||
b->Lb = (36 * t_equalized[2*CBZ_T_SAMPLES/3] -
|
||||
45 * t_equalized[CBZ_T_SAMPLES/3] -
|
||||
(9 << CBZ_T_Q)) >> 1;
|
||||
|
||||
b->La = ((27 * (t_equalized[CBZ_T_SAMPLES/3] -
|
||||
t_equalized[2*CBZ_T_SAMPLES/3]) +
|
||||
(7 << CBZ_T_Q)) >> 1) + CBZ_T_ONE;
|
||||
|
||||
g_debug ("t(1/3) %f, t(2/3) %f",
|
||||
(double)t_equalized[CBZ_T_SAMPLES/3]/(double)CBZ_T_ONE,
|
||||
(double)t_equalized[2*CBZ_T_SAMPLES/3]/(double)CBZ_T_ONE);
|
||||
|
||||
g_debug ("L -> t coefficients: %f, %f, %f",
|
||||
(double)b->La/(double)CBZ_T_ONE,
|
||||
(double)b->Lb/(double)CBZ_T_ONE,
|
||||
(double)b->Lc/(double)CBZ_T_ONE);
|
||||
|
||||
|
||||
/*
|
||||
* For debugging, you can load these values into a spreadsheet and graph
|
||||
* them to see how well the approximation matches the data
|
||||
*/
|
||||
for (i = 0; i < CBZ_T_SAMPLES; ++i)
|
||||
{
|
||||
g_print ("%f, %f, %f\n",
|
||||
(double)(i*CBZ_T_STEP)/(double)CBZ_T_ONE,
|
||||
(double)(t_equalized[i])/(double)CBZ_T_ONE,
|
||||
(double)(clutter_bezier_L2t(b,i*CBZ_T_STEP))/(double)CBZ_T_ONE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Moves a control point at indx to location represented by knot
|
||||
*/
|
||||
void
|
||||
_clutter_bezier_adjust (ClutterBezier * b, ClutterKnot * knot, guint indx)
|
||||
{
|
||||
guint x[4], y[4];
|
||||
|
||||
g_assert (indx < 4);
|
||||
|
||||
x[0] = b->dx;
|
||||
y[0] = b->dy;
|
||||
|
||||
x[1] = b->cx / 3 + x[0];
|
||||
y[1] = b->cy / 3 + y[0];
|
||||
|
||||
x[2] = b->bx / 3 + b->cx + x[1];
|
||||
y[2] = b->by / 3 + b->cy + y[1];
|
||||
|
||||
x[3] = b->ax + x[0] + b->cx + b->bx;
|
||||
y[3] = b->ay + y[0] + b->cy + b->by;
|
||||
|
||||
x[indx] = knot->x;
|
||||
y[indx] = knot->y;
|
||||
|
||||
_clutter_bezier_init (b, x[0], y[0], x[1], y[1], x[2], y[2], x[3], y[3]);
|
||||
}
|
||||
|
||||
guint
|
||||
_clutter_bezier_get_length (const ClutterBezier *b)
|
||||
{
|
||||
return b->length;
|
||||
}
|
||||
65
clutter/clutter/clutter-bezier.h
Normal file
65
clutter/clutter/clutter-bezier.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Tomas Frydrych <tf@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2006, 2007 OpenedHand
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_BEZIER_H__
|
||||
#define __CLUTTER_BEZIER_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include "clutter-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* This is used in _clutter_bezier_advance to represent the full
|
||||
length of the bezier curve. Anything less than that represents a
|
||||
fraction of the length */
|
||||
#define CLUTTER_BEZIER_MAX_LENGTH (1 << 18)
|
||||
|
||||
typedef struct _ClutterBezier ClutterBezier;
|
||||
|
||||
ClutterBezier *_clutter_bezier_new (void);
|
||||
|
||||
void _clutter_bezier_free (ClutterBezier * b);
|
||||
|
||||
ClutterBezier *_clutter_bezier_clone_and_move (const ClutterBezier *b,
|
||||
gint x,
|
||||
gint y);
|
||||
|
||||
void _clutter_bezier_advance (const ClutterBezier *b,
|
||||
gint L,
|
||||
ClutterKnot *knot);
|
||||
|
||||
void _clutter_bezier_init (ClutterBezier *b,
|
||||
gint x_0, gint y_0,
|
||||
gint x_1, gint y_1,
|
||||
gint x_2, gint y_2,
|
||||
gint x_3, gint y_3);
|
||||
|
||||
void _clutter_bezier_adjust (ClutterBezier *b,
|
||||
ClutterKnot *knot,
|
||||
guint indx);
|
||||
|
||||
guint _clutter_bezier_get_length (const ClutterBezier *b);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_BEZIER_H__ */
|
||||
@@ -23,9 +23,8 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterBinLayout:
|
||||
*
|
||||
* A simple layout manager
|
||||
* SECTION:clutter-bin-layout
|
||||
* @short_description: A simple layout manager
|
||||
*
|
||||
* #ClutterBinLayout is a layout manager which implements the following
|
||||
* policy:
|
||||
@@ -37,27 +36,258 @@
|
||||
* of the other;
|
||||
* - for each layer there are horizontal and vertical
|
||||
* alignment policies.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* #ClutterBinLayout is available since Clutter 1.2
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "clutter/clutter-actor-private.h"
|
||||
#include "clutter/clutter-animatable.h"
|
||||
#include "clutter/clutter-bin-layout.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-enum-types.h"
|
||||
#include "clutter/clutter-layout-meta.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
|
||||
#include "deprecated/clutter-container.h"
|
||||
#include "deprecated/clutter-bin-layout.h"
|
||||
|
||||
G_DEFINE_TYPE (ClutterBinLayout,
|
||||
clutter_bin_layout,
|
||||
CLUTTER_TYPE_LAYOUT_MANAGER)
|
||||
#include "clutter-actor-private.h"
|
||||
#include "clutter-animatable.h"
|
||||
#include "clutter-child-meta.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-enum-types.h"
|
||||
#include "clutter-layout-meta.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
#define CLUTTER_TYPE_BIN_LAYER (clutter_bin_layer_get_type ())
|
||||
#define CLUTTER_BIN_LAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BIN_LAYER, ClutterBinLayer))
|
||||
#define CLUTTER_IS_BIN_LAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BIN_LAYER))
|
||||
|
||||
typedef struct _ClutterBinLayer ClutterBinLayer;
|
||||
typedef struct _ClutterLayoutMetaClass ClutterBinLayerClass;
|
||||
|
||||
struct _ClutterBinLayoutPrivate
|
||||
{
|
||||
ClutterBinAlignment x_align;
|
||||
ClutterBinAlignment y_align;
|
||||
|
||||
ClutterContainer *container;
|
||||
};
|
||||
|
||||
struct _ClutterBinLayer
|
||||
{
|
||||
ClutterLayoutMeta parent_instance;
|
||||
|
||||
ClutterBinAlignment x_align;
|
||||
ClutterBinAlignment y_align;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_LAYER_0,
|
||||
|
||||
PROP_LAYER_X_ALIGN,
|
||||
PROP_LAYER_Y_ALIGN,
|
||||
|
||||
PROP_LAYER_LAST
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_X_ALIGN,
|
||||
PROP_Y_ALIGN,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static GParamSpec *layer_props[PROP_LAYER_LAST] = { NULL, };
|
||||
static GParamSpec *bin_props[PROP_LAST] = { NULL, };
|
||||
|
||||
GType clutter_bin_layer_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE (ClutterBinLayer,
|
||||
clutter_bin_layer,
|
||||
CLUTTER_TYPE_LAYOUT_META)
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterBinLayout,
|
||||
clutter_bin_layout,
|
||||
CLUTTER_TYPE_LAYOUT_MANAGER)
|
||||
|
||||
/*
|
||||
* ClutterBinLayer
|
||||
*/
|
||||
|
||||
static void
|
||||
set_layer_x_align (ClutterBinLayer *self,
|
||||
ClutterBinAlignment alignment)
|
||||
{
|
||||
ClutterLayoutManager *manager;
|
||||
ClutterLayoutMeta *meta;
|
||||
|
||||
if (self->x_align == alignment)
|
||||
return;
|
||||
|
||||
self->x_align = alignment;
|
||||
|
||||
meta = CLUTTER_LAYOUT_META (self);
|
||||
manager = clutter_layout_meta_get_manager (meta);
|
||||
clutter_layout_manager_layout_changed (manager);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), layer_props[PROP_LAYER_X_ALIGN]);
|
||||
}
|
||||
|
||||
static void
|
||||
set_layer_y_align (ClutterBinLayer *self,
|
||||
ClutterBinAlignment alignment)
|
||||
{
|
||||
ClutterLayoutManager *manager;
|
||||
ClutterLayoutMeta *meta;
|
||||
|
||||
if (self->y_align == alignment)
|
||||
return;
|
||||
|
||||
self->y_align = alignment;
|
||||
|
||||
meta = CLUTTER_LAYOUT_META (self);
|
||||
manager = clutter_layout_meta_get_manager (meta);
|
||||
clutter_layout_manager_layout_changed (manager);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), layer_props[PROP_LAYER_Y_ALIGN]);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bin_layer_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterBinLayer *layer = CLUTTER_BIN_LAYER (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_LAYER_X_ALIGN:
|
||||
set_layer_x_align (layer, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
case PROP_LAYER_Y_ALIGN:
|
||||
set_layer_y_align (layer, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bin_layer_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterBinLayer *layer = CLUTTER_BIN_LAYER (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_LAYER_X_ALIGN:
|
||||
g_value_set_enum (value, layer->x_align);
|
||||
break;
|
||||
|
||||
case PROP_LAYER_Y_ALIGN:
|
||||
g_value_set_enum (value, layer->y_align);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bin_layer_class_init (ClutterBinLayerClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->set_property = clutter_bin_layer_set_property;
|
||||
gobject_class->get_property = clutter_bin_layer_get_property;
|
||||
|
||||
layer_props[PROP_LAYER_X_ALIGN] =
|
||||
g_param_spec_enum ("x-align",
|
||||
P_("Horizontal Alignment"),
|
||||
P_("Horizontal alignment for the actor "
|
||||
"inside the layout manager"),
|
||||
CLUTTER_TYPE_BIN_ALIGNMENT,
|
||||
CLUTTER_BIN_ALIGNMENT_CENTER,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
layer_props[PROP_LAYER_Y_ALIGN] =
|
||||
g_param_spec_enum ("y-align",
|
||||
P_("Vertical Alignment"),
|
||||
P_("Vertical alignment for the actor "
|
||||
"inside the layout manager"),
|
||||
CLUTTER_TYPE_BIN_ALIGNMENT,
|
||||
CLUTTER_BIN_ALIGNMENT_CENTER,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (gobject_class,
|
||||
PROP_LAYER_LAST,
|
||||
layer_props);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bin_layer_init (ClutterBinLayer *layer)
|
||||
{
|
||||
layer->x_align = CLUTTER_BIN_ALIGNMENT_CENTER;
|
||||
layer->y_align = CLUTTER_BIN_ALIGNMENT_CENTER;
|
||||
}
|
||||
|
||||
/*
|
||||
* ClutterBinLayout
|
||||
*/
|
||||
|
||||
static void
|
||||
set_x_align (ClutterBinLayout *self,
|
||||
ClutterBinAlignment alignment)
|
||||
{
|
||||
ClutterBinLayoutPrivate *priv = self->priv;
|
||||
|
||||
if (priv->x_align != alignment)
|
||||
{
|
||||
ClutterLayoutManager *manager;
|
||||
|
||||
priv->x_align = alignment;
|
||||
|
||||
manager = CLUTTER_LAYOUT_MANAGER (self);
|
||||
clutter_layout_manager_layout_changed (manager);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), bin_props[PROP_X_ALIGN]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_y_align (ClutterBinLayout *self,
|
||||
ClutterBinAlignment alignment)
|
||||
{
|
||||
ClutterBinLayoutPrivate *priv = self->priv;
|
||||
|
||||
if (priv->y_align != alignment)
|
||||
{
|
||||
ClutterLayoutManager *manager;
|
||||
|
||||
priv->y_align = alignment;
|
||||
|
||||
manager = CLUTTER_LAYOUT_MANAGER (self);
|
||||
clutter_layout_manager_layout_changed (manager);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), bin_props[PROP_Y_ALIGN]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bin_layout_get_preferred_width (ClutterLayoutManager *manager,
|
||||
ClutterActor *container,
|
||||
ClutterContainer *container,
|
||||
gfloat for_height,
|
||||
gfloat *min_width_p,
|
||||
gfloat *nat_width_p)
|
||||
@@ -94,7 +324,7 @@ clutter_bin_layout_get_preferred_width (ClutterLayoutManager *manager,
|
||||
|
||||
static void
|
||||
clutter_bin_layout_get_preferred_height (ClutterLayoutManager *manager,
|
||||
ClutterActor *container,
|
||||
ClutterContainer *container,
|
||||
gfloat for_width,
|
||||
gfloat *min_height_p,
|
||||
gfloat *nat_height_p)
|
||||
@@ -129,6 +359,29 @@ clutter_bin_layout_get_preferred_height (ClutterLayoutManager *manager,
|
||||
*nat_height_p = nat_height;
|
||||
}
|
||||
|
||||
static gdouble
|
||||
get_bin_alignment_factor (ClutterBinAlignment alignment,
|
||||
ClutterTextDirection text_dir)
|
||||
{
|
||||
switch (alignment)
|
||||
{
|
||||
case CLUTTER_BIN_ALIGNMENT_CENTER:
|
||||
return 0.5;
|
||||
|
||||
case CLUTTER_BIN_ALIGNMENT_START:
|
||||
return text_dir == CLUTTER_TEXT_DIRECTION_LTR ? 0.0 : 1.0;
|
||||
|
||||
case CLUTTER_BIN_ALIGNMENT_END:
|
||||
return text_dir == CLUTTER_TEXT_DIRECTION_LTR ? 1.0 : 0.0;
|
||||
|
||||
case CLUTTER_BIN_ALIGNMENT_FIXED:
|
||||
case CLUTTER_BIN_ALIGNMENT_FILL:
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
static gdouble
|
||||
get_actor_align_factor (ClutterActorAlign alignment)
|
||||
{
|
||||
@@ -152,8 +405,9 @@ get_actor_align_factor (ClutterActorAlign alignment)
|
||||
|
||||
static void
|
||||
clutter_bin_layout_allocate (ClutterLayoutManager *manager,
|
||||
ClutterActor *container,
|
||||
const ClutterActorBox *allocation)
|
||||
ClutterContainer *container,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags)
|
||||
{
|
||||
gfloat allocation_x, allocation_y;
|
||||
gfloat available_w, available_h;
|
||||
@@ -168,6 +422,8 @@ clutter_bin_layout_allocate (ClutterLayoutManager *manager,
|
||||
clutter_actor_iter_init (&iter, actor);
|
||||
while (clutter_actor_iter_next (&iter, &child))
|
||||
{
|
||||
ClutterLayoutMeta *meta;
|
||||
ClutterBinLayer *layer;
|
||||
ClutterActorBox child_alloc = { 0, };
|
||||
gdouble x_align, y_align;
|
||||
gboolean x_fill, y_fill, is_fixed_position_set;
|
||||
@@ -176,6 +432,11 @@ clutter_bin_layout_allocate (ClutterLayoutManager *manager,
|
||||
if (!clutter_actor_is_visible (child))
|
||||
continue;
|
||||
|
||||
meta = clutter_layout_manager_get_child_meta (manager,
|
||||
container,
|
||||
child);
|
||||
layer = CLUTTER_BIN_LAYER (meta);
|
||||
|
||||
fixed_x = fixed_y = 0.f;
|
||||
g_object_get (child,
|
||||
"fixed-position-set", &is_fixed_position_set,
|
||||
@@ -183,7 +444,11 @@ clutter_bin_layout_allocate (ClutterLayoutManager *manager,
|
||||
"fixed-y", &fixed_y,
|
||||
NULL);
|
||||
|
||||
if (is_fixed_position_set)
|
||||
/* XXX:2.0 - remove the FIXED alignment, and just use the fixed position
|
||||
* of the actor if one is set
|
||||
*/
|
||||
if (is_fixed_position_set ||
|
||||
layer->x_align == CLUTTER_BIN_ALIGNMENT_FIXED)
|
||||
{
|
||||
if (is_fixed_position_set)
|
||||
child_alloc.x1 = fixed_x;
|
||||
@@ -193,7 +458,8 @@ clutter_bin_layout_allocate (ClutterLayoutManager *manager,
|
||||
else
|
||||
child_alloc.x1 = allocation_x;
|
||||
|
||||
if (is_fixed_position_set)
|
||||
if (is_fixed_position_set ||
|
||||
layer->y_align == CLUTTER_BIN_ALIGNMENT_FIXED)
|
||||
{
|
||||
if (is_fixed_position_set)
|
||||
child_alloc.y1 = fixed_y;
|
||||
@@ -216,10 +482,14 @@ clutter_bin_layout_allocate (ClutterLayoutManager *manager,
|
||||
}
|
||||
else
|
||||
{
|
||||
x_fill = FALSE;
|
||||
ClutterTextDirection text_dir;
|
||||
|
||||
x_fill = (layer->x_align == CLUTTER_BIN_ALIGNMENT_FILL);
|
||||
|
||||
text_dir = clutter_actor_get_text_direction (child);
|
||||
|
||||
if (!is_fixed_position_set)
|
||||
x_align = 0.5;
|
||||
x_align = get_bin_alignment_factor (layer->x_align, text_dir);
|
||||
else
|
||||
x_align = 0.0;
|
||||
}
|
||||
@@ -234,46 +504,381 @@ clutter_bin_layout_allocate (ClutterLayoutManager *manager,
|
||||
}
|
||||
else
|
||||
{
|
||||
y_fill = FALSE;
|
||||
y_fill = (layer->y_align == CLUTTER_BIN_ALIGNMENT_FILL);
|
||||
|
||||
if (!is_fixed_position_set)
|
||||
y_align = 0.5;
|
||||
y_align = get_bin_alignment_factor (layer->y_align,
|
||||
CLUTTER_TEXT_DIRECTION_LTR);
|
||||
else
|
||||
y_align = 0.0;
|
||||
}
|
||||
|
||||
clutter_actor_allocate_align_fill (child, &child_alloc,
|
||||
x_align, y_align,
|
||||
x_fill, y_fill);
|
||||
x_fill, y_fill,
|
||||
flags);
|
||||
}
|
||||
}
|
||||
|
||||
static GType
|
||||
clutter_bin_layout_get_child_meta_type (ClutterLayoutManager *manager)
|
||||
{
|
||||
return CLUTTER_TYPE_BIN_LAYER;
|
||||
}
|
||||
|
||||
static ClutterLayoutMeta *
|
||||
clutter_bin_layout_create_child_meta (ClutterLayoutManager *manager,
|
||||
ClutterContainer *container,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterBinLayoutPrivate *priv;
|
||||
|
||||
priv = CLUTTER_BIN_LAYOUT (manager)->priv;
|
||||
|
||||
return g_object_new (CLUTTER_TYPE_BIN_LAYER,
|
||||
"container", container,
|
||||
"actor", actor,
|
||||
"manager", manager,
|
||||
"x-align", priv->x_align,
|
||||
"y_align", priv->y_align,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bin_layout_set_container (ClutterLayoutManager *manager,
|
||||
ClutterContainer *container)
|
||||
{
|
||||
ClutterBinLayoutPrivate *priv;
|
||||
ClutterLayoutManagerClass *parent_class;
|
||||
|
||||
priv = CLUTTER_BIN_LAYOUT (manager)->priv;
|
||||
priv->container = container;
|
||||
|
||||
parent_class = CLUTTER_LAYOUT_MANAGER_CLASS (clutter_bin_layout_parent_class);
|
||||
parent_class->set_container (manager, container);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bin_layout_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterBinLayout *layout = CLUTTER_BIN_LAYOUT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_X_ALIGN:
|
||||
set_x_align (layout, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
case PROP_Y_ALIGN:
|
||||
set_y_align (layout, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bin_layout_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterBinLayoutPrivate *priv;
|
||||
|
||||
priv = CLUTTER_BIN_LAYOUT (gobject)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_X_ALIGN:
|
||||
g_value_set_enum (value, priv->x_align);
|
||||
break;
|
||||
|
||||
case PROP_Y_ALIGN:
|
||||
g_value_set_enum (value, priv->y_align);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bin_layout_class_init (ClutterBinLayoutClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterLayoutManagerClass *layout_class =
|
||||
CLUTTER_LAYOUT_MANAGER_CLASS (klass);
|
||||
|
||||
/**
|
||||
* ClutterBinLayout:x-align:
|
||||
*
|
||||
* The default horizontal alignment policy for actors managed
|
||||
* by the #ClutterBinLayout
|
||||
*
|
||||
* Since: 1.2
|
||||
*
|
||||
* Deprecated: 1.12: Use the #ClutterActor:x-expand and the
|
||||
* #ClutterActor:x-align properties on #ClutterActor instead.
|
||||
*/
|
||||
bin_props[PROP_X_ALIGN] =
|
||||
g_param_spec_enum ("x-align",
|
||||
P_("Horizontal Alignment"),
|
||||
P_("Default horizontal alignment for the actors "
|
||||
"inside the layout manager"),
|
||||
CLUTTER_TYPE_BIN_ALIGNMENT,
|
||||
CLUTTER_BIN_ALIGNMENT_CENTER,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* ClutterBinLayout:y-align:
|
||||
*
|
||||
* The default vertical alignment policy for actors managed
|
||||
* by the #ClutterBinLayout
|
||||
*
|
||||
* Since: 1.2
|
||||
*
|
||||
* Deprecated: 1.12: Use the #ClutterActor:y-expand and the
|
||||
* #ClutterActor:y-align properties on #ClutterActor instead.
|
||||
*/
|
||||
bin_props[PROP_Y_ALIGN] =
|
||||
g_param_spec_enum ("y-align",
|
||||
P_("Vertical Alignment"),
|
||||
P_("Default vertical alignment for the actors "
|
||||
"inside the layout manager"),
|
||||
CLUTTER_TYPE_BIN_ALIGNMENT,
|
||||
CLUTTER_BIN_ALIGNMENT_CENTER,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
gobject_class->set_property = clutter_bin_layout_set_property;
|
||||
gobject_class->get_property = clutter_bin_layout_get_property;
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, bin_props);
|
||||
|
||||
layout_class->get_preferred_width = clutter_bin_layout_get_preferred_width;
|
||||
layout_class->get_preferred_height = clutter_bin_layout_get_preferred_height;
|
||||
layout_class->allocate = clutter_bin_layout_allocate;
|
||||
layout_class->create_child_meta = clutter_bin_layout_create_child_meta;
|
||||
layout_class->get_child_meta_type = clutter_bin_layout_get_child_meta_type;
|
||||
layout_class->set_container = clutter_bin_layout_set_container;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bin_layout_init (ClutterBinLayout *self)
|
||||
{
|
||||
self->priv = clutter_bin_layout_get_instance_private (self);
|
||||
|
||||
self->priv->x_align = CLUTTER_BIN_ALIGNMENT_CENTER;
|
||||
self->priv->y_align = CLUTTER_BIN_ALIGNMENT_CENTER;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_bin_layout_new:
|
||||
* @x_align: the default alignment policy to be used on the
|
||||
* horizontal axis
|
||||
* @y_align: the default alignment policy to be used on the
|
||||
* vertical axis
|
||||
*
|
||||
* Creates a new #ClutterBinLayout layout manager
|
||||
*
|
||||
* Return value: the newly created layout manager
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
ClutterLayoutManager *
|
||||
clutter_bin_layout_new (void)
|
||||
clutter_bin_layout_new (ClutterBinAlignment x_align,
|
||||
ClutterBinAlignment y_align)
|
||||
{
|
||||
return g_object_new (CLUTTER_TYPE_BIN_LAYOUT,
|
||||
"x-align", x_align,
|
||||
"y-align", y_align,
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -22,30 +22,51 @@
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_BIN_LAYOUT_H__
|
||||
#define __CLUTTER_BIN_LAYOUT_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-layout-manager.h"
|
||||
#include <clutter/clutter-layout-manager.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_BIN_LAYOUT (clutter_bin_layout_get_type ())
|
||||
#define CLUTTER_TYPE_BIN_LAYOUT (clutter_bin_layout_get_type ())
|
||||
#define CLUTTER_BIN_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BIN_LAYOUT, ClutterBinLayout))
|
||||
#define CLUTTER_IS_BIN_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BIN_LAYOUT))
|
||||
#define CLUTTER_BIN_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BIN_LAYOUT, ClutterBinLayoutClass))
|
||||
#define CLUTTER_IS_BIN_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BIN_LAYOUT))
|
||||
#define CLUTTER_BIN_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BIN_LAYOUT, ClutterBinLayoutClass))
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterBinLayout,
|
||||
clutter_bin_layout,
|
||||
CLUTTER,
|
||||
BIN_LAYOUT,
|
||||
ClutterLayoutManager)
|
||||
typedef struct _ClutterBinLayout ClutterBinLayout;
|
||||
typedef struct _ClutterBinLayoutPrivate ClutterBinLayoutPrivate;
|
||||
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
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterLayoutManager parent_instance;
|
||||
|
||||
ClutterBinLayoutPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterBinLayoutClass:
|
||||
*
|
||||
* The #ClutterBinLayoutClass structure contains only private
|
||||
* data and should be accessed using the provided API
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
struct _ClutterBinLayoutClass
|
||||
{
|
||||
@@ -54,6 +75,12 @@ struct _ClutterBinLayoutClass
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterLayoutManager * clutter_bin_layout_new (void);
|
||||
GType clutter_bin_layout_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterLayoutManager * clutter_bin_layout_new (ClutterBinAlignment x_align,
|
||||
ClutterBinAlignment y_align);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_BIN_LAYOUT_H__ */
|
||||
|
||||
@@ -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 [class@Constraint] that binds the
|
||||
* position or the size of the [class@Actor] to which it is applied
|
||||
* to the the position or the size of another [class@Actor], or
|
||||
* #ClutterBindConstraint is a #ClutterConstraint that binds the
|
||||
* position or the size of the #ClutterActor to which it is applied
|
||||
* to the the position or the size of another #ClutterActor, or
|
||||
* "source".
|
||||
*
|
||||
* An offset can be applied to the constraint, to avoid overlapping. The offset
|
||||
* can also be animated. For instance, the following code will set up three
|
||||
* actors to be bound to the same origin:
|
||||
*
|
||||
* ```c
|
||||
* |[<!-- language="C" -->
|
||||
* // source
|
||||
* rect[0] = clutter_actor_new ();
|
||||
* clutter_actor_set_background_color (rect[0], &red_color);
|
||||
* rect[0] = clutter_rectangle_new_with_color (&red_color);
|
||||
* clutter_actor_set_position (rect[0], x_pos, y_pos);
|
||||
* clutter_actor_set_size (rect[0], 100, 100);
|
||||
*
|
||||
* // second rectangle
|
||||
* rect[1] = clutter_actor_new ();
|
||||
* clutter_actor_set_background_color (rect[1], &green_color);
|
||||
* rect[1] = clutter_rectangle_new_with_color (&green_color);
|
||||
* clutter_actor_set_size (rect[1], 100, 100);
|
||||
* clutter_actor_set_opacity (rect[1], 0);
|
||||
*
|
||||
@@ -55,8 +53,7 @@
|
||||
* clutter_actor_add_constraint_with_name (rect[1], "green-y", constraint);
|
||||
*
|
||||
* // third rectangle
|
||||
* rect[2] = clutter_actor_new ();
|
||||
* clutter_actor_set_background_color (rect[2], &blue_color);
|
||||
* rect[2] = clutter_rectangle_new_with_color (&blue_color);
|
||||
* clutter_actor_set_size (rect[2], 100, 100);
|
||||
* clutter_actor_set_opacity (rect[2], 0);
|
||||
*
|
||||
@@ -64,12 +61,12 @@
|
||||
* clutter_actor_add_constraint_with_name (rect[2], "blue-x", constraint);
|
||||
* constraint = clutter_bind_constraint_new (rect[0], CLUTTER_BIND_Y, 0.0);
|
||||
* clutter_actor_add_constraint_with_name (rect[2], "blue-y", constraint);
|
||||
* ```
|
||||
* ]|
|
||||
*
|
||||
* The following code animates the second and third rectangles to "expand"
|
||||
* them horizontally from underneath the first rectangle:
|
||||
*
|
||||
* ```c
|
||||
* |[<!-- language="C" -->
|
||||
* clutter_actor_animate (rect[1], CLUTTER_EASE_OUT_CUBIC, 250,
|
||||
* "@constraints.green-x.offset", 100.0,
|
||||
* "opacity", 255,
|
||||
@@ -78,21 +75,27 @@
|
||||
* "@constraints.blue-x.offset", 200.0,
|
||||
* "opacity", 255,
|
||||
* NULL);
|
||||
* ```
|
||||
* ]|
|
||||
*
|
||||
* #ClutterBindConstraint is available since Clutter 1.4
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "clutter/clutter-bind-constraint.h"
|
||||
#include "clutter-bind-constraint.h"
|
||||
|
||||
#include "clutter/clutter-actor-meta-private.h"
|
||||
#include "clutter/clutter-actor-private.h"
|
||||
#include "clutter/clutter-constraint.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-enum-types.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#include "clutter-actor-meta-private.h"
|
||||
#include "clutter-actor-private.h"
|
||||
#include "clutter-constraint.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-enum-types.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
#define CLUTTER_BIND_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BIND_CONSTRAINT, ClutterBindConstraintClass))
|
||||
#define CLUTTER_IS_BIND_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BIND_CONSTRAINT))
|
||||
#define CLUTTER_BIND_CONSTRAINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BIND_CONSTRAINT, ClutterBindConstraintClass))
|
||||
|
||||
struct _ClutterBindConstraint
|
||||
{
|
||||
@@ -104,6 +107,11 @@ struct _ClutterBindConstraint
|
||||
gfloat offset;
|
||||
};
|
||||
|
||||
struct _ClutterBindConstraintClass
|
||||
{
|
||||
ClutterConstraintClass parent_class;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
@@ -117,9 +125,9 @@ enum
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
G_DEFINE_FINAL_TYPE (ClutterBindConstraint,
|
||||
clutter_bind_constraint,
|
||||
CLUTTER_TYPE_CONSTRAINT);
|
||||
G_DEFINE_TYPE (ClutterBindConstraint,
|
||||
clutter_bind_constraint,
|
||||
CLUTTER_TYPE_CONSTRAINT);
|
||||
|
||||
static void
|
||||
source_queue_relayout (ClutterActor *source,
|
||||
@@ -136,58 +144,6 @@ source_destroyed (ClutterActor *actor,
|
||||
bind->source = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bind_constraint_update_preferred_size (ClutterConstraint *constraint,
|
||||
ClutterActor *actor,
|
||||
ClutterOrientation direction,
|
||||
float for_size,
|
||||
float *minimum_size,
|
||||
float *natural_size)
|
||||
{
|
||||
ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint);
|
||||
float source_min, source_nat;
|
||||
|
||||
if (bind->source == NULL)
|
||||
return;
|
||||
|
||||
/* only these bindings affect the preferred size */
|
||||
if (!(bind->coordinate == CLUTTER_BIND_WIDTH ||
|
||||
bind->coordinate == CLUTTER_BIND_HEIGHT ||
|
||||
bind->coordinate == CLUTTER_BIND_SIZE ||
|
||||
bind->coordinate == CLUTTER_BIND_ALL))
|
||||
return;
|
||||
|
||||
if (clutter_actor_contains (bind->source, actor))
|
||||
return;
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case CLUTTER_ORIENTATION_HORIZONTAL:
|
||||
if (bind->coordinate != CLUTTER_BIND_HEIGHT)
|
||||
{
|
||||
clutter_actor_get_preferred_width (bind->source, for_size,
|
||||
&source_min,
|
||||
&source_nat);
|
||||
|
||||
*minimum_size = source_min;
|
||||
*natural_size = source_nat;
|
||||
}
|
||||
break;
|
||||
|
||||
case CLUTTER_ORIENTATION_VERTICAL:
|
||||
if (bind->coordinate != CLUTTER_BIND_WIDTH)
|
||||
{
|
||||
clutter_actor_get_preferred_height (bind->source, for_size,
|
||||
&source_min,
|
||||
&source_nat);
|
||||
|
||||
*minimum_size = source_min;
|
||||
*natural_size = source_nat;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_bind_constraint_update_allocation (ClutterConstraint *constraint,
|
||||
ClutterActor *actor,
|
||||
@@ -196,9 +152,7 @@ clutter_bind_constraint_update_allocation (ClutterConstraint *constraint,
|
||||
ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint);
|
||||
gfloat source_width, source_height;
|
||||
gfloat actor_width, actor_height;
|
||||
graphene_point3d_t source_position;
|
||||
|
||||
source_position = GRAPHENE_POINT3D_INIT (0.f, 0.f, 0.f);
|
||||
ClutterVertex source_position = { 0., };
|
||||
|
||||
if (bind->source == NULL)
|
||||
return;
|
||||
@@ -372,8 +326,6 @@ clutter_bind_constraint_class_init (ClutterBindConstraintClass *klass)
|
||||
meta_class->set_actor = clutter_bind_constraint_set_actor;
|
||||
|
||||
constraint_class->update_allocation = clutter_bind_constraint_update_allocation;
|
||||
constraint_class->update_preferred_size = clutter_bind_constraint_update_preferred_size;
|
||||
|
||||
/**
|
||||
* ClutterBindConstraint:source:
|
||||
*
|
||||
@@ -381,39 +333,45 @@ clutter_bind_constraint_class_init (ClutterBindConstraintClass *klass)
|
||||
*
|
||||
* The #ClutterActor must not be contained inside the actor associated
|
||||
* to the constraint.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
obj_props[PROP_SOURCE] =
|
||||
g_param_spec_object ("source", NULL, NULL,
|
||||
g_param_spec_object ("source",
|
||||
P_("Source"),
|
||||
P_("The source of the binding"),
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT);
|
||||
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT);
|
||||
|
||||
/**
|
||||
* ClutterBindConstraint:coordinate:
|
||||
*
|
||||
* The coordinate to be bound
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
obj_props[PROP_COORDINATE] =
|
||||
g_param_spec_enum ("coordinate", NULL, NULL,
|
||||
g_param_spec_enum ("coordinate",
|
||||
P_("Coordinate"),
|
||||
P_("The coordinate to bind"),
|
||||
CLUTTER_TYPE_BIND_COORDINATE,
|
||||
CLUTTER_BIND_X,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT);
|
||||
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT);
|
||||
|
||||
/**
|
||||
* ClutterBindConstraint:offset:
|
||||
*
|
||||
* The offset, in pixels, to be applied to the binding
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
obj_props[PROP_OFFSET] =
|
||||
g_param_spec_float ("offset", NULL, NULL,
|
||||
g_param_spec_float ("offset",
|
||||
P_("Offset"),
|
||||
P_("The offset in pixels to apply to the binding"),
|
||||
-G_MAXFLOAT, G_MAXFLOAT,
|
||||
0.0f,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT);
|
||||
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT);
|
||||
|
||||
g_object_class_install_properties (gobject_class,
|
||||
PROP_LAST,
|
||||
@@ -440,6 +398,8 @@ clutter_bind_constraint_init (ClutterBindConstraint *self)
|
||||
* the given @coordinate of the position of @source
|
||||
*
|
||||
* Return value: the newly created #ClutterBindConstraint
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
ClutterConstraint *
|
||||
clutter_bind_constraint_new (ClutterActor *source,
|
||||
@@ -461,6 +421,8 @@ clutter_bind_constraint_new (ClutterActor *source,
|
||||
* @source: (allow-none): a #ClutterActor, or %NULL to unset the source
|
||||
*
|
||||
* Sets the source #ClutterActor for the constraint
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
clutter_bind_constraint_set_source (ClutterBindConstraint *constraint,
|
||||
@@ -523,9 +485,11 @@ clutter_bind_constraint_set_source (ClutterBindConstraint *constraint,
|
||||
* clutter_bind_constraint_get_source:
|
||||
* @constraint: a #ClutterBindConstraint
|
||||
*
|
||||
* Retrieves the #ClutterActor set using [method@Clutter.BindConstraint.set_source]
|
||||
* Retrieves the #ClutterActor set using clutter_bind_constraint_set_source()
|
||||
*
|
||||
* Return value: (transfer none): a pointer to the source actor
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_bind_constraint_get_source (ClutterBindConstraint *constraint)
|
||||
@@ -541,6 +505,8 @@ clutter_bind_constraint_get_source (ClutterBindConstraint *constraint)
|
||||
* @coordinate: the coordinate to bind
|
||||
*
|
||||
* Sets the coordinate to bind in the constraint
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
clutter_bind_constraint_set_coordinate (ClutterBindConstraint *constraint,
|
||||
@@ -566,6 +532,8 @@ clutter_bind_constraint_set_coordinate (ClutterBindConstraint *constraint,
|
||||
* Retrieves the bound coordinate of the constraint
|
||||
*
|
||||
* Return value: the bound coordinate
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
ClutterBindCoordinate
|
||||
clutter_bind_constraint_get_coordinate (ClutterBindConstraint *constraint)
|
||||
@@ -582,6 +550,8 @@ clutter_bind_constraint_get_coordinate (ClutterBindConstraint *constraint)
|
||||
* @offset: the offset to apply, in pixels
|
||||
*
|
||||
* Sets the offset to be applied to the constraint
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
clutter_bind_constraint_set_offset (ClutterBindConstraint *constraint,
|
||||
@@ -604,9 +574,11 @@ clutter_bind_constraint_set_offset (ClutterBindConstraint *constraint,
|
||||
* clutter_bind_constraint_get_offset:
|
||||
* @constraint: a #ClutterBindConstraint
|
||||
*
|
||||
* Retrieves the offset set using [method@Clutter.BindConstraint.set_offset]
|
||||
* Retrieves the offset set using clutter_bind_constraint_set_offset()
|
||||
*
|
||||
* Return value: the offset, in pixels
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
gfloat
|
||||
clutter_bind_constraint_get_offset (ClutterBindConstraint *bind)
|
||||
|
||||
@@ -22,21 +22,34 @@
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_BIND_CONSTRAINT_H__
|
||||
#define __CLUTTER_BIND_CONSTRAINT_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-constraint.h"
|
||||
#include <clutter/clutter-constraint.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_BIND_CONSTRAINT (clutter_bind_constraint_get_type ())
|
||||
#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))
|
||||
|
||||
/**
|
||||
* ClutterBindConstraint:
|
||||
*
|
||||
* #ClutterBindConstraint is an opaque structure
|
||||
* whose members cannot be directly accessed
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
typedef struct _ClutterBindConstraint ClutterBindConstraint;
|
||||
typedef struct _ClutterBindConstraintClass ClutterBindConstraintClass;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_FINAL_TYPE (ClutterBindConstraint, clutter_bind_constraint,
|
||||
CLUTTER, BIND_CONSTRAINT, ClutterConstraint)
|
||||
GType clutter_bind_constraint_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterConstraint * clutter_bind_constraint_new (ClutterActor *source,
|
||||
@@ -60,3 +73,5 @@ CLUTTER_EXPORT
|
||||
gfloat clutter_bind_constraint_get_offset (ClutterBindConstraint *constraint);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_BIND_CONSTRAINT_H__ */
|
||||
|
||||
@@ -22,9 +22,8 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterBindingPool
|
||||
*
|
||||
* Pool for key bindings
|
||||
* SECTION:clutter-binding-pool
|
||||
* @short_description: Pool for key bindings
|
||||
*
|
||||
* #ClutterBindingPool is a data structure holding a set of key bindings.
|
||||
* Each key binding associates a key symbol (eventually with modifiers)
|
||||
@@ -39,7 +38,7 @@
|
||||
* inside their class initialization function and then install actions
|
||||
* like this:
|
||||
*
|
||||
* ```c
|
||||
* |[<!-- language="C" -->
|
||||
* static void
|
||||
* foo_class_init (FooClass *klass)
|
||||
* {
|
||||
@@ -56,23 +55,23 @@
|
||||
* G_CALLBACK (foo_action_move_up),
|
||||
* NULL, NULL);
|
||||
* }
|
||||
* ```
|
||||
* ]|
|
||||
*
|
||||
* The callback has a signature of:
|
||||
*
|
||||
* ```c
|
||||
* |[<!-- language="C" -->
|
||||
* gboolean (* callback) (GObject *instance,
|
||||
* const gchar *action_name,
|
||||
* guint key_val,
|
||||
* ClutterModifierType modifiers,
|
||||
* gpointer user_data);
|
||||
* ```
|
||||
* ]|
|
||||
*
|
||||
* The actor should then override the [signal@Actor::key-press-event] and
|
||||
* use [method@BindingPool.activate] to match a [struct@Event] key event
|
||||
* structure to one of the actions:
|
||||
* The actor should then override the #ClutterActor::key-press-event and
|
||||
* use clutter_binding_pool_activate() to match a #ClutterKeyEvent structure
|
||||
* to one of the actions:
|
||||
*
|
||||
* ```c
|
||||
* |[<!-- language="C" -->
|
||||
* ClutterBindingPool *pool;
|
||||
*
|
||||
* // retrieve the binding pool for the type of the actor
|
||||
@@ -85,28 +84,34 @@
|
||||
* key_event->keyval,
|
||||
* key_event->modifier_state,
|
||||
* 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
|
||||
* blocked (using [method@BindingPool.block_action]) or if the
|
||||
* blocked (using clutter_binding_pool_block_action()) or if the
|
||||
* key binding handler returned %FALSE.
|
||||
*
|
||||
* #ClutterBindingPool is available since Clutter 1.0
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter/clutter-binding-pool.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-enum-types.h"
|
||||
#include "clutter/clutter-marshal.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#include "clutter-binding-pool.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-enum-types.h"
|
||||
#include "clutter-marshal.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
#define BINDING_MOD_MASK ((CLUTTER_SHIFT_MASK | \
|
||||
#define CLUTTER_BINDING_POOL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), CLUTTER_TYPE_BINDING_POOL, ClutterBindingPoolClass))
|
||||
#define CLUTTER_IS_BINDING_POOL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CLUTTER_TYPE_BINDING_POOL))
|
||||
#define CLUTTER_BINDING_POOL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CLUTTER_TYPE_BINDING_POOL, ClutterBindingPoolClass))
|
||||
|
||||
#define BINDING_MOD_MASK ((CLUTTER_SHIFT_MASK | \
|
||||
CLUTTER_CONTROL_MASK | \
|
||||
CLUTTER_MOD1_MASK | \
|
||||
CLUTTER_SUPER_MASK | \
|
||||
CLUTTER_HYPER_MASK | \
|
||||
CLUTTER_META_MASK) | CLUTTER_RELEASE_MASK)
|
||||
CLUTTER_MOD1_MASK | \
|
||||
CLUTTER_SUPER_MASK | \
|
||||
CLUTTER_HYPER_MASK | \
|
||||
CLUTTER_META_MASK) | CLUTTER_RELEASE_MASK)
|
||||
|
||||
typedef struct _ClutterBindingEntry ClutterBindingEntry;
|
||||
|
||||
@@ -123,6 +128,11 @@ struct _ClutterBindingPool
|
||||
GHashTable *entries_hash;
|
||||
};
|
||||
|
||||
struct _ClutterBindingPoolClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
struct _ClutterBindingEntry
|
||||
{
|
||||
gchar *name; /* interned string, do not free */
|
||||
@@ -146,7 +156,7 @@ enum
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
G_DEFINE_FINAL_TYPE (ClutterBindingPool, clutter_binding_pool, G_TYPE_OBJECT);
|
||||
G_DEFINE_TYPE (ClutterBindingPool, clutter_binding_pool, G_TYPE_OBJECT);
|
||||
|
||||
static guint
|
||||
binding_entry_hash (gconstpointer v)
|
||||
@@ -179,7 +189,7 @@ binding_entry_new (const gchar *name,
|
||||
|
||||
modifiers = modifiers & BINDING_MOD_MASK;
|
||||
|
||||
entry = g_new0 (ClutterBindingEntry, 1);
|
||||
entry = g_slice_new (ClutterBindingEntry);
|
||||
entry->key_val = key_val;
|
||||
entry->modifiers = modifiers;
|
||||
entry->name = (gchar *) g_intern_string (name);
|
||||
@@ -211,7 +221,7 @@ binding_entry_free (gpointer data)
|
||||
|
||||
g_closure_unref (entry->closure);
|
||||
|
||||
g_free (entry);
|
||||
g_slice_free (ClutterBindingEntry, entry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,12 +307,15 @@ clutter_binding_pool_class_init (ClutterBindingPoolClass *klass)
|
||||
* ClutterBindingPool:name:
|
||||
*
|
||||
* The unique name of the #ClutterBindingPool.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
obj_props[PROP_NAME] =
|
||||
g_param_spec_string ("name", NULL, NULL,
|
||||
g_param_spec_string ("name",
|
||||
P_("Name"),
|
||||
P_("The unique name of the binding pool"),
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
CLUTTER_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (gobject_class,
|
||||
@@ -327,11 +340,13 @@ clutter_binding_pool_init (ClutterBindingPool *pool)
|
||||
*
|
||||
* Creates a new #ClutterBindingPool that can be used to store
|
||||
* key bindings for an actor. The @name must be a unique identifier
|
||||
* for the binding pool, so that [func@Clutter.BindingPool.find] will
|
||||
* for the binding pool, so that clutter_binding_pool_find() will
|
||||
* be able to return the correct binding pool.
|
||||
*
|
||||
* Return value: the newly created binding pool with the given
|
||||
* name. Use g_object_unref() when done.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
ClutterBindingPool *
|
||||
clutter_binding_pool_new (const gchar *name)
|
||||
@@ -358,22 +373,24 @@ clutter_binding_pool_new (const gchar *name)
|
||||
*
|
||||
* Retrieves the #ClutterBindingPool for the given #GObject class
|
||||
* and, eventually, creates it. This function is a wrapper around
|
||||
* [ctor@Clutter.BindingPool.new] and uses the class type name as the
|
||||
* clutter_binding_pool_new() and uses the class type name as the
|
||||
* unique name for the binding pool.
|
||||
*
|
||||
* Calling this function multiple times will return the same
|
||||
* #ClutterBindingPool.
|
||||
*
|
||||
* A binding pool for a class can also be retrieved using
|
||||
* [func@Clutter.BindingPool.find] with the class type name:
|
||||
* clutter_binding_pool_find() with the class type name:
|
||||
*
|
||||
* ```
|
||||
* |[
|
||||
* pool = clutter_binding_pool_find (G_OBJECT_TYPE_NAME (instance));
|
||||
* ```
|
||||
* ]|
|
||||
*
|
||||
* Return value: (transfer none): the binding pool for the given class.
|
||||
* The returned #ClutterBindingPool is owned by Clutter and should not
|
||||
* be freed directly
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
ClutterBindingPool *
|
||||
clutter_binding_pool_get_for_class (gpointer klass)
|
||||
@@ -404,6 +421,8 @@ clutter_binding_pool_get_for_class (gpointer klass)
|
||||
* Finds the #ClutterBindingPool with @name.
|
||||
*
|
||||
* Return value: (transfer none): a pointer to the #ClutterBindingPool, or %NULL
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
ClutterBindingPool *
|
||||
clutter_binding_pool_find (const gchar *name)
|
||||
@@ -429,7 +448,7 @@ clutter_binding_pool_find (const gchar *name)
|
||||
* @action_name: the name of the action
|
||||
* @key_val: key symbol
|
||||
* @modifiers: bitmask of modifiers
|
||||
* @callback: function to be called
|
||||
* @callback: (type Clutter.BindingActionFunc): function to be called
|
||||
* when the action is activated
|
||||
* @data: data to be passed to @callback
|
||||
* @notify: function to be called when the action is removed
|
||||
@@ -441,11 +460,13 @@ clutter_binding_pool_find (const gchar *name)
|
||||
* The same action name can be used for multiple @key_val, @modifiers
|
||||
* pairs.
|
||||
*
|
||||
* When an action has been activated using [method@Clutter.BindingPool.activate]
|
||||
* When an action has been activated using clutter_binding_pool_activate()
|
||||
* the passed @callback will be invoked (with @data).
|
||||
*
|
||||
* Actions can be blocked with [method@Clutter.BindingPool.block_action]
|
||||
* and then unblocked using [method@Clutter.BindingPool.unblock_action].
|
||||
* Actions can be blocked with clutter_binding_pool_block_action()
|
||||
* and then unblocked using clutter_binding_pool_unblock_action().
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_binding_pool_install_action (ClutterBindingPool *pool,
|
||||
@@ -501,7 +522,7 @@ clutter_binding_pool_install_action (ClutterBindingPool *pool,
|
||||
* @modifiers: bitmask of modifiers
|
||||
* @closure: a #GClosure
|
||||
*
|
||||
* A #GClosure variant of [method@Clutter.BindingPool.install_action].
|
||||
* A #GClosure variant of clutter_binding_pool_install_action().
|
||||
*
|
||||
* Installs a new action inside a #ClutterBindingPool. The action
|
||||
* is bound to @key_val and @modifiers.
|
||||
@@ -509,11 +530,13 @@ clutter_binding_pool_install_action (ClutterBindingPool *pool,
|
||||
* The same action name can be used for multiple @key_val, @modifiers
|
||||
* pairs.
|
||||
*
|
||||
* When an action has been activated using [method@Clutter.BindingPool.activate]
|
||||
* When an action has been activated using clutter_binding_pool_activate()
|
||||
* the passed @closure will be invoked.
|
||||
*
|
||||
* Actions can be blocked with [method@Clutter.BindingPool.block_action]
|
||||
* and then unblocked using [method@Clutter.BindingPool.unblock_action].
|
||||
* Actions can be blocked with clutter_binding_pool_block_action()
|
||||
* and then unblocked using clutter_binding_pool_unblock_action().
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_binding_pool_install_closure (ClutterBindingPool *pool,
|
||||
@@ -568,13 +591,15 @@ clutter_binding_pool_install_closure (ClutterBindingPool *pool,
|
||||
* from the pool
|
||||
*
|
||||
* Allows overriding the action for @key_val and @modifiers inside a
|
||||
* #ClutterBindingPool. See [method@Clutter.BindingPool.install_action].
|
||||
* #ClutterBindingPool. See clutter_binding_pool_install_action().
|
||||
*
|
||||
* When an action has been activated using [method@Clutter.BindingPool.activate]
|
||||
* When an action has been activated using clutter_binding_pool_activate()
|
||||
* the passed @callback will be invoked (with @data).
|
||||
*
|
||||
* Actions can be blocked with [method@Clutter.BindingPool.block_action]
|
||||
* and then unblocked using [method@Clutter.BindingPool.unblock_action].
|
||||
* Actions can be blocked with clutter_binding_pool_block_action()
|
||||
* and then unblocked using clutter_binding_pool_unblock_action().
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_binding_pool_override_action (ClutterBindingPool *pool,
|
||||
@@ -627,16 +652,18 @@ clutter_binding_pool_override_action (ClutterBindingPool *pool,
|
||||
* @modifiers: bitmask of modifiers
|
||||
* @closure: a #GClosure
|
||||
*
|
||||
* A #GClosure variant of [method@Clutter.BindingPool.override_action].
|
||||
* A #GClosure variant of clutter_binding_pool_override_action().
|
||||
*
|
||||
* Allows overriding the action for @key_val and @modifiers inside a
|
||||
* #ClutterBindingPool. See [method@Clutter.BindingPool.install_closure].
|
||||
* #ClutterBindingPool. See clutter_binding_pool_install_closure().
|
||||
*
|
||||
* When an action has been activated using [method@Clutter.BindingPool.activate]
|
||||
* When an action has been activated using clutter_binding_pool_activate()
|
||||
* the passed @callback will be invoked (with @data).
|
||||
*
|
||||
* Actions can be blocked with [method@Clutter.BindingPool.block_action]
|
||||
* and then unblocked using [method@Clutter.BindingPool.unblock_action].
|
||||
* Actions can be blocked with clutter_binding_pool_block_action()
|
||||
* and then unblocked using clutter_binding_pool_unblock_action().
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_binding_pool_override_closure (ClutterBindingPool *pool,
|
||||
@@ -690,6 +717,8 @@ clutter_binding_pool_override_closure (ClutterBindingPool *pool,
|
||||
* Return value: the name of the action, if found, or %NULL. The
|
||||
* returned string is owned by the binding pool and should never
|
||||
* be modified or freed
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
const gchar *
|
||||
clutter_binding_pool_find_action (ClutterBindingPool *pool,
|
||||
@@ -716,6 +745,8 @@ clutter_binding_pool_find_action (ClutterBindingPool *pool,
|
||||
*
|
||||
* Removes the action matching the given @key_val, @modifiers pair,
|
||||
* if any exists.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_binding_pool_remove_action (ClutterBindingPool *pool,
|
||||
@@ -801,23 +832,25 @@ clutter_binding_entry_invoke (ClutterBindingEntry *entry,
|
||||
*
|
||||
* The callback has the following signature:
|
||||
*
|
||||
* ```
|
||||
* |[
|
||||
* void (* callback) (GObject *gobject,
|
||||
* const gchar *action_name,
|
||||
* guint key_val,
|
||||
* ClutterModifierType modifiers,
|
||||
* gpointer user_data);
|
||||
* ```
|
||||
* ]|
|
||||
*
|
||||
* Where the #GObject instance is @gobject and the user data
|
||||
* is the one passed when installing the action with
|
||||
* [method@Clutter.BindingPool.install_action].
|
||||
* clutter_binding_pool_install_action().
|
||||
*
|
||||
* If the action bound to the @key_val, @modifiers pair has been
|
||||
* blocked using [method@Clutter.BindingPool.block_action], the callback
|
||||
* blocked using clutter_binding_pool_block_action(), the callback
|
||||
* will not be invoked, and this function will return %FALSE.
|
||||
*
|
||||
* Return value: %TRUE if an action was found and was activated
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
gboolean
|
||||
clutter_binding_pool_activate (ClutterBindingPool *pool,
|
||||
@@ -849,6 +882,8 @@ clutter_binding_pool_activate (ClutterBindingPool *pool,
|
||||
* @action_name: an action name
|
||||
*
|
||||
* Blocks all the actions with name @action_name inside @pool.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_binding_pool_block_action (ClutterBindingPool *pool,
|
||||
@@ -876,8 +911,10 @@ clutter_binding_pool_block_action (ClutterBindingPool *pool,
|
||||
* Unblockes all the actions with name @action_name inside @pool.
|
||||
*
|
||||
* Unblocking an action does not cause the callback bound to it to
|
||||
* be invoked in case [method@Clutter.BindingPool.activate] was called on
|
||||
* an action previously blocked with [method@Clutter.BindingPool.block_action].
|
||||
* be invoked in case clutter_binding_pool_activate() was called on
|
||||
* an action previously blocked with clutter_binding_pool_block_action().
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_binding_pool_unblock_action (ClutterBindingPool *pool,
|
||||
|
||||
@@ -21,26 +21,58 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_BINDING_POOL_H__
|
||||
#define __CLUTTER_BINDING_POOL_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "clutter/clutter-event.h"
|
||||
#include <clutter/clutter-event.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_BINDING_POOL (clutter_binding_pool_get_type ())
|
||||
#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))
|
||||
|
||||
/**
|
||||
* ClutterBindingPool:
|
||||
*
|
||||
* Container of key bindings. The #ClutterBindingPool struct is
|
||||
* private.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
typedef struct _ClutterBindingPool ClutterBindingPool;
|
||||
typedef struct _ClutterBindingPoolClass ClutterBindingPoolClass;
|
||||
|
||||
/**
|
||||
* ClutterBindingActionFunc:
|
||||
* @gobject: a #GObject
|
||||
* @action_name: the name of the action
|
||||
* @key_val: the key symbol
|
||||
* @modifiers: bitmask of the modifier flags
|
||||
* @user_data: data passed to the function
|
||||
*
|
||||
* The prototype for the callback function registered with
|
||||
* clutter_binding_pool_install_action() and invoked by
|
||||
* clutter_binding_pool_activate().
|
||||
*
|
||||
* Return value: the function should return %TRUE if the key
|
||||
* binding has been handled, and return %FALSE otherwise
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
typedef gboolean (* ClutterBindingActionFunc) (GObject *gobject,
|
||||
const gchar *action_name,
|
||||
guint key_val,
|
||||
ClutterModifierType modifiers,
|
||||
gpointer user_data);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_FINAL_TYPE (ClutterBindingPool,
|
||||
clutter_binding_pool,
|
||||
CLUTTER,
|
||||
BINDING_POOL,
|
||||
GObject)
|
||||
GType clutter_binding_pool_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterBindingPool * clutter_binding_pool_new (const gchar *name);
|
||||
@@ -99,3 +131,5 @@ void clutter_binding_pool_unblock_action (ClutterBindingPool
|
||||
const gchar *action_name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_BINDING_POOL_H__ */
|
||||
|
||||
@@ -23,21 +23,31 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterBlurEffect:
|
||||
*
|
||||
* A blur effect
|
||||
* SECTION:clutter-blur-effect
|
||||
* @short_description: A blur effect
|
||||
* @see_also: #ClutterEffect, #ClutterOffscreenEffect
|
||||
*
|
||||
* #ClutterBlurEffect is a sub-class of #ClutterEffect that allows blurring a
|
||||
* actor and its contents.
|
||||
*
|
||||
* #ClutterBlurEffect is available since Clutter 1.4
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-blur-effect.h"
|
||||
#define CLUTTER_BLUR_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BLUR_EFFECT, ClutterBlurEffectClass))
|
||||
#define CLUTTER_IS_BLUR_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BLUR_EFFECT))
|
||||
#define CLUTTER_BLUR_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BLUR_EFFECT, ClutterBlurEffectClass))
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||
|
||||
#include "clutter-blur-effect.h"
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-offscreen-effect.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
#define BLUR_PADDING 2
|
||||
|
||||
@@ -62,58 +72,117 @@ static const gchar *box_blur_glsl_shader =
|
||||
" cogl_texel /= 9.0;\n";
|
||||
#undef SAMPLE
|
||||
|
||||
typedef struct _ClutterBlurEffectPrivate
|
||||
struct _ClutterBlurEffect
|
||||
{
|
||||
ClutterOffscreenEffect parent_instance;
|
||||
|
||||
/* a back pointer to our actor, so that we can query it */
|
||||
ClutterActor *actor;
|
||||
|
||||
gint pixel_step_uniform;
|
||||
|
||||
gint tex_width;
|
||||
gint tex_height;
|
||||
|
||||
CoglPipeline *pipeline;
|
||||
} ClutterBlurEffectPrivate;
|
||||
};
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterBlurEffect,
|
||||
clutter_blur_effect,
|
||||
CLUTTER_TYPE_OFFSCREEN_EFFECT);
|
||||
|
||||
static CoglPipeline *
|
||||
clutter_blur_effect_create_pipeline (ClutterOffscreenEffect *effect,
|
||||
CoglTexture *texture)
|
||||
struct _ClutterBlurEffectClass
|
||||
{
|
||||
ClutterBlurEffect *blur_effect = CLUTTER_BLUR_EFFECT (effect);
|
||||
ClutterBlurEffectPrivate *priv =
|
||||
clutter_blur_effect_get_instance_private (blur_effect);
|
||||
ClutterOffscreenEffectClass parent_class;
|
||||
|
||||
if (priv->pixel_step_uniform > -1)
|
||||
CoglPipeline *base_pipeline;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ClutterBlurEffect,
|
||||
clutter_blur_effect,
|
||||
CLUTTER_TYPE_OFFSCREEN_EFFECT);
|
||||
|
||||
static gboolean
|
||||
clutter_blur_effect_pre_paint (ClutterEffect *effect)
|
||||
{
|
||||
ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect);
|
||||
ClutterEffectClass *parent_class;
|
||||
|
||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
|
||||
return FALSE;
|
||||
|
||||
self->actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
|
||||
if (self->actor == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
|
||||
{
|
||||
float pixel_step[2];
|
||||
int tex_width, tex_height;
|
||||
|
||||
tex_width = cogl_texture_get_width (texture);
|
||||
tex_height = cogl_texture_get_height (texture);
|
||||
|
||||
pixel_step[0] = 1.0f / tex_width;
|
||||
pixel_step[1] = 1.0f / tex_height;
|
||||
|
||||
cogl_pipeline_set_uniform_float (priv->pipeline,
|
||||
priv->pixel_step_uniform,
|
||||
2, /* n_components */
|
||||
1, /* count */
|
||||
pixel_step);
|
||||
/* 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;
|
||||
}
|
||||
|
||||
cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture);
|
||||
parent_class = CLUTTER_EFFECT_CLASS (clutter_blur_effect_parent_class);
|
||||
if (parent_class->pre_paint (effect))
|
||||
{
|
||||
ClutterOffscreenEffect *offscreen_effect =
|
||||
CLUTTER_OFFSCREEN_EFFECT (effect);
|
||||
CoglHandle texture;
|
||||
|
||||
return g_object_ref (priv->pipeline);
|
||||
texture = clutter_offscreen_effect_get_texture (offscreen_effect);
|
||||
self->tex_width = cogl_texture_get_width (texture);
|
||||
self->tex_height = cogl_texture_get_height (texture);
|
||||
|
||||
if (self->pixel_step_uniform > -1)
|
||||
{
|
||||
gfloat pixel_step[2];
|
||||
|
||||
pixel_step[0] = 1.0f / self->tex_width;
|
||||
pixel_step[1] = 1.0f / self->tex_height;
|
||||
|
||||
cogl_pipeline_set_uniform_float (self->pipeline,
|
||||
self->pixel_step_uniform,
|
||||
2, /* n_components */
|
||||
1, /* count */
|
||||
pixel_step);
|
||||
}
|
||||
|
||||
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect)
|
||||
{
|
||||
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
|
||||
clutter_blur_effect_modify_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume)
|
||||
clutter_blur_effect_get_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
gfloat cur_width, cur_height;
|
||||
graphene_point3d_t origin;
|
||||
ClutterVertex origin;
|
||||
|
||||
clutter_paint_volume_get_origin (volume, &origin);
|
||||
cur_width = clutter_paint_volume_get_width (volume);
|
||||
@@ -134,10 +203,12 @@ static void
|
||||
clutter_blur_effect_dispose (GObject *gobject)
|
||||
{
|
||||
ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (gobject);
|
||||
ClutterBlurEffectPrivate *priv =
|
||||
clutter_blur_effect_get_instance_private (self);
|
||||
|
||||
g_clear_object (&priv->pipeline);
|
||||
if (self->pipeline != NULL)
|
||||
{
|
||||
cogl_object_unref (self->pipeline);
|
||||
self->pipeline = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (clutter_blur_effect_parent_class)->dispose (gobject);
|
||||
}
|
||||
@@ -151,53 +222,51 @@ clutter_blur_effect_class_init (ClutterBlurEffectClass *klass)
|
||||
|
||||
gobject_class->dispose = clutter_blur_effect_dispose;
|
||||
|
||||
effect_class->modify_paint_volume = clutter_blur_effect_modify_paint_volume;
|
||||
effect_class->pre_paint = clutter_blur_effect_pre_paint;
|
||||
effect_class->get_paint_volume = clutter_blur_effect_get_paint_volume;
|
||||
|
||||
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
||||
offscreen_class->create_pipeline = clutter_blur_effect_create_pipeline;
|
||||
offscreen_class->paint_target = clutter_blur_effect_paint_target;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_blur_effect_init (ClutterBlurEffect *self)
|
||||
{
|
||||
ClutterBlurEffectClass *klass = CLUTTER_BLUR_EFFECT_GET_CLASS (self);
|
||||
ClutterBlurEffectPrivate *priv =
|
||||
clutter_blur_effect_get_instance_private (self);
|
||||
|
||||
if (G_UNLIKELY (klass->base_pipeline == NULL))
|
||||
{
|
||||
CoglSnippet *snippet;
|
||||
ClutterContext *context = _clutter_context_get_default ();
|
||||
ClutterBackend *backend = clutter_context_get_backend (context);
|
||||
CoglContext *cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
CoglContext *ctx =
|
||||
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
|
||||
klass->base_pipeline = cogl_pipeline_new (cogl_context);
|
||||
cogl_pipeline_set_static_name (klass->base_pipeline,
|
||||
"ClutterBlurEffect (base pipeline)");
|
||||
klass->base_pipeline = cogl_pipeline_new (ctx);
|
||||
|
||||
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
|
||||
box_blur_glsl_declarations,
|
||||
NULL);
|
||||
cogl_snippet_set_replace (snippet, box_blur_glsl_shader);
|
||||
cogl_pipeline_add_layer_snippet (klass->base_pipeline, 0, snippet);
|
||||
g_object_unref (snippet);
|
||||
cogl_object_unref (snippet);
|
||||
|
||||
cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0);
|
||||
}
|
||||
|
||||
priv->pipeline = cogl_pipeline_copy (klass->base_pipeline);
|
||||
self->pipeline = cogl_pipeline_copy (klass->base_pipeline);
|
||||
|
||||
priv->pixel_step_uniform =
|
||||
cogl_pipeline_get_uniform_location (priv->pipeline, "pixel_step");
|
||||
self->pixel_step_uniform =
|
||||
cogl_pipeline_get_uniform_location (self->pipeline, "pixel_step");
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_blur_effect_new:
|
||||
*
|
||||
* Creates a new #ClutterBlurEffect to be used with
|
||||
* [method@Clutter.Actor.add_effect]
|
||||
* clutter_actor_add_effect()
|
||||
*
|
||||
* Return value: the newly created #ClutterBlurEffect or %NULL
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
ClutterEffect *
|
||||
clutter_blur_effect_new (void)
|
||||
|
||||
@@ -22,33 +22,38 @@
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_BLUR_EFFECT_H__
|
||||
#define __CLUTTER_BLUR_EFFECT_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-effect.h"
|
||||
#include "clutter/clutter-offscreen-effect.h"
|
||||
#include <clutter/clutter-effect.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_BLUR_EFFECT (clutter_blur_effect_get_type ())
|
||||
#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))
|
||||
|
||||
/**
|
||||
* ClutterBlurEffect:
|
||||
*
|
||||
* #ClutterBlurEffect is an opaque structure
|
||||
* whose members cannot be accessed directly
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
typedef struct _ClutterBlurEffect ClutterBlurEffect;
|
||||
typedef struct _ClutterBlurEffectClass ClutterBlurEffectClass;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterBlurEffect,
|
||||
clutter_blur_effect,
|
||||
CLUTTER, BLUR_EFFECT,
|
||||
ClutterOffscreenEffect)
|
||||
|
||||
struct _ClutterBlurEffectClass
|
||||
{
|
||||
ClutterOffscreenEffectClass parent_class;
|
||||
|
||||
CoglPipeline *base_pipeline;
|
||||
};
|
||||
GType clutter_blur_effect_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterEffect *clutter_blur_effect_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_BLUR_EFFECT_H__ */
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Endless OS Foundation, LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _ClutterBlur ClutterBlur;
|
||||
|
||||
ClutterBlur * clutter_blur_new (CoglTexture *texture,
|
||||
float radius);
|
||||
|
||||
void clutter_blur_apply (ClutterBlur *blur);
|
||||
|
||||
CoglTexture * clutter_blur_get_texture (ClutterBlur *blur);
|
||||
|
||||
void clutter_blur_free (ClutterBlur *blur);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,435 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Endless OS Foundation, LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-blur-private.h"
|
||||
|
||||
#include "clutter/clutter-backend.h"
|
||||
|
||||
/**
|
||||
* ClutterBlur:
|
||||
*
|
||||
* Blur textures
|
||||
*
|
||||
* #ClutterBlur is a moderately fast gaussian blur implementation.
|
||||
*
|
||||
* # Optimizations
|
||||
*
|
||||
* There are a number of optimizations in place to make this blur implementation
|
||||
* real-time. All in all, the implementation performs best when using large
|
||||
* blur-radii that allow downscaling the texture to smaller sizes, at small
|
||||
* radii where no downscaling is possible this can easily halve the framerate.
|
||||
*
|
||||
* ## Multipass
|
||||
*
|
||||
* It is implemented in 2 passes: vertical and horizontal.
|
||||
*
|
||||
* ## Downscaling
|
||||
*
|
||||
* #ClutterBlur uses dynamic downscaling to speed up blurring. Downscaling
|
||||
* happens in factors of 2 (the image is downscaled either by 2, 4, 8, 16, …)
|
||||
* and depends on the blur radius, the texture size, among others.
|
||||
*
|
||||
* The texture is drawn into a downscaled framebuffer; the blur passes are
|
||||
* applied on the downscaled texture contents; and finally, the blurred
|
||||
* contents are drawn
|
||||
* upscaled again.
|
||||
*
|
||||
* ## Hardware Interpolation
|
||||
*
|
||||
* This blur implementation cuts down the number of sampling operations by
|
||||
* exploiting the hardware interpolation that is performed when sampling between
|
||||
* pixel boundaries. This technique is described at:
|
||||
*
|
||||
* http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
|
||||
*
|
||||
* ## Incremental gauss-factor calculation
|
||||
*
|
||||
* The kernel values for the gaussian kernel are computed incrementally instead
|
||||
* of running the expensive calculations multiple times inside the blur shader.
|
||||
* The implementation is based on the algorithm presented by K. Turkowski in
|
||||
* GPU Gems 3, chapter 40:
|
||||
*
|
||||
* https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch40.html
|
||||
*
|
||||
*/
|
||||
|
||||
static const char *gaussian_blur_glsl_declarations =
|
||||
"uniform float sigma; \n"
|
||||
"uniform float pixel_step; \n"
|
||||
"uniform vec2 direction; \n";
|
||||
|
||||
static const char *gaussian_blur_glsl =
|
||||
" vec2 uv = vec2 (cogl_tex_coord.st); \n"
|
||||
" \n"
|
||||
" vec3 gauss_coefficient; \n"
|
||||
" gauss_coefficient.x = 1.0 / (sqrt (2.0 * 3.14159265) * sigma); \n"
|
||||
" gauss_coefficient.y = exp (-0.5 / (sigma * sigma)); \n"
|
||||
" gauss_coefficient.z = gauss_coefficient.y * gauss_coefficient.y; \n"
|
||||
" \n"
|
||||
" float gauss_coefficient_total = gauss_coefficient.x; \n"
|
||||
" \n"
|
||||
" vec4 ret = texture2D (cogl_sampler, uv) * gauss_coefficient.x; \n"
|
||||
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
|
||||
" \n"
|
||||
" int n_steps = int (ceil (1.5 * sigma)) * 2; \n"
|
||||
" \n"
|
||||
" for (int i = 1; i <= n_steps; i += 2) { \n"
|
||||
" float coefficient_subtotal = gauss_coefficient.x; \n"
|
||||
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
|
||||
" coefficient_subtotal += gauss_coefficient.x; \n"
|
||||
" \n"
|
||||
" float gauss_ratio = gauss_coefficient.x / coefficient_subtotal; \n"
|
||||
" \n"
|
||||
" float foffset = float (i) + gauss_ratio; \n"
|
||||
" vec2 offset = direction * foffset * pixel_step; \n"
|
||||
" \n"
|
||||
" ret += texture2D (cogl_sampler, uv + offset) * coefficient_subtotal; \n"
|
||||
" ret += texture2D (cogl_sampler, uv - offset) * coefficient_subtotal; \n"
|
||||
" \n"
|
||||
" gauss_coefficient_total += 2.0 * coefficient_subtotal; \n"
|
||||
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
|
||||
" } \n"
|
||||
" \n"
|
||||
" cogl_texel = ret / gauss_coefficient_total; \n";
|
||||
|
||||
#define MIN_DOWNSCALE_SIZE 256.f
|
||||
#define MAX_SIGMA 6.f
|
||||
|
||||
enum
|
||||
{
|
||||
VERTICAL,
|
||||
HORIZONTAL,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglPipeline *pipeline;
|
||||
CoglTexture *texture;
|
||||
int orientation;
|
||||
} BlurPass;
|
||||
|
||||
struct _ClutterBlur
|
||||
{
|
||||
CoglTexture *source_texture;
|
||||
float sigma;
|
||||
float downscale_factor;
|
||||
|
||||
BlurPass pass[2];
|
||||
};
|
||||
|
||||
static CoglPipeline*
|
||||
create_blur_pipeline (CoglContext *ctx)
|
||||
{
|
||||
static CoglPipelineKey blur_pipeline_key = "clutter-blur-pipeline-private";
|
||||
CoglPipeline *blur_pipeline;
|
||||
|
||||
blur_pipeline =
|
||||
cogl_context_get_named_pipeline (ctx, &blur_pipeline_key);
|
||||
|
||||
if (G_UNLIKELY (blur_pipeline == NULL))
|
||||
{
|
||||
CoglSnippet *snippet;
|
||||
|
||||
blur_pipeline = cogl_pipeline_new (ctx);
|
||||
cogl_pipeline_set_static_name (blur_pipeline, "ClutterBlur");
|
||||
cogl_pipeline_set_layer_null_texture (blur_pipeline, 0);
|
||||
cogl_pipeline_set_layer_filters (blur_pipeline,
|
||||
0,
|
||||
COGL_PIPELINE_FILTER_LINEAR,
|
||||
COGL_PIPELINE_FILTER_LINEAR);
|
||||
cogl_pipeline_set_layer_wrap_mode (blur_pipeline,
|
||||
0,
|
||||
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
||||
|
||||
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
|
||||
gaussian_blur_glsl_declarations,
|
||||
NULL);
|
||||
cogl_snippet_set_replace (snippet, gaussian_blur_glsl);
|
||||
cogl_pipeline_add_layer_snippet (blur_pipeline, 0, snippet);
|
||||
g_object_unref (snippet);
|
||||
|
||||
cogl_context_set_named_pipeline (ctx, &blur_pipeline_key, blur_pipeline);
|
||||
}
|
||||
|
||||
return cogl_pipeline_copy (blur_pipeline);
|
||||
}
|
||||
|
||||
static void
|
||||
update_blur_uniforms (ClutterBlur *blur,
|
||||
BlurPass *pass)
|
||||
{
|
||||
gboolean vertical = pass->orientation == VERTICAL;
|
||||
int sigma_uniform;
|
||||
int pixel_step_uniform;
|
||||
int direction_uniform;
|
||||
|
||||
pixel_step_uniform =
|
||||
cogl_pipeline_get_uniform_location (pass->pipeline, "pixel_step");
|
||||
if (pixel_step_uniform > -1)
|
||||
{
|
||||
float pixel_step;
|
||||
|
||||
if (vertical)
|
||||
pixel_step = 1.f / cogl_texture_get_height (pass->texture);
|
||||
else
|
||||
pixel_step = 1.f / cogl_texture_get_width (pass->texture);
|
||||
|
||||
cogl_pipeline_set_uniform_1f (pass->pipeline,
|
||||
pixel_step_uniform,
|
||||
pixel_step);
|
||||
}
|
||||
|
||||
sigma_uniform = cogl_pipeline_get_uniform_location (pass->pipeline, "sigma");
|
||||
if (sigma_uniform > -1)
|
||||
{
|
||||
cogl_pipeline_set_uniform_1f (pass->pipeline,
|
||||
sigma_uniform,
|
||||
blur->sigma / blur->downscale_factor);
|
||||
}
|
||||
|
||||
direction_uniform =
|
||||
cogl_pipeline_get_uniform_location (pass->pipeline, "direction");
|
||||
if (direction_uniform > -1)
|
||||
{
|
||||
gboolean horizontal = !vertical;
|
||||
float direction[2] = {
|
||||
horizontal,
|
||||
vertical,
|
||||
};
|
||||
|
||||
cogl_pipeline_set_uniform_float (pass->pipeline,
|
||||
direction_uniform,
|
||||
2, 1,
|
||||
direction);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
create_fbo (ClutterBlur *blur,
|
||||
CoglContext *ctx,
|
||||
BlurPass *pass)
|
||||
{
|
||||
float scaled_height;
|
||||
float scaled_width;
|
||||
float height;
|
||||
float width;
|
||||
|
||||
g_clear_object (&pass->texture);
|
||||
g_clear_object (&pass->framebuffer);
|
||||
|
||||
width = cogl_texture_get_width (blur->source_texture);
|
||||
height = cogl_texture_get_height (blur->source_texture);
|
||||
scaled_width = floorf (width / blur->downscale_factor);
|
||||
scaled_height = floorf (height / blur->downscale_factor);
|
||||
|
||||
pass->texture = cogl_texture_2d_new_with_size (ctx,
|
||||
(int) scaled_width,
|
||||
(int) scaled_height);
|
||||
if (!pass->texture)
|
||||
return FALSE;
|
||||
|
||||
pass->framebuffer =
|
||||
COGL_FRAMEBUFFER (cogl_offscreen_new_with_texture (pass->texture));
|
||||
if (!pass->framebuffer)
|
||||
{
|
||||
g_warning ("%s: Unable to create an Offscreen buffer", G_STRLOC);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cogl_framebuffer_orthographic (pass->framebuffer,
|
||||
0.0, 0.0,
|
||||
scaled_width,
|
||||
scaled_height,
|
||||
0.0, 1.0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
setup_blur_pass (ClutterBlur *blur,
|
||||
BlurPass *pass,
|
||||
int orientation,
|
||||
CoglTexture *texture)
|
||||
{
|
||||
CoglContext *context = cogl_texture_get_context (texture);
|
||||
pass->orientation = orientation;
|
||||
pass->pipeline = create_blur_pipeline (context);
|
||||
cogl_pipeline_set_layer_texture (pass->pipeline, 0, texture);
|
||||
|
||||
if (!create_fbo (blur, context, pass))
|
||||
return FALSE;
|
||||
|
||||
update_blur_uniforms (blur, pass);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static float
|
||||
calculate_downscale_factor (float width,
|
||||
float height,
|
||||
float sigma)
|
||||
{
|
||||
float downscale_factor = 1.f;
|
||||
float scaled_width = width;
|
||||
float scaled_height = height;
|
||||
float scaled_sigma = sigma;
|
||||
|
||||
/* This is the algorithm used by Firefox; keep downscaling until either the
|
||||
* blur radius is lower than the threshold, or the downscaled texture is too
|
||||
* small.
|
||||
*/
|
||||
while (scaled_sigma > MAX_SIGMA &&
|
||||
scaled_width > MIN_DOWNSCALE_SIZE &&
|
||||
scaled_height > MIN_DOWNSCALE_SIZE)
|
||||
{
|
||||
downscale_factor *= 2.f;
|
||||
|
||||
scaled_width = width / downscale_factor;
|
||||
scaled_height = height / downscale_factor;
|
||||
scaled_sigma = sigma / downscale_factor;
|
||||
}
|
||||
|
||||
return downscale_factor;
|
||||
}
|
||||
|
||||
static void
|
||||
apply_blur_pass (BlurPass *pass)
|
||||
{
|
||||
CoglColor transparent;
|
||||
|
||||
cogl_color_init_from_4f (&transparent, 0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
cogl_framebuffer_clear (pass->framebuffer,
|
||||
COGL_BUFFER_BIT_COLOR,
|
||||
&transparent);
|
||||
|
||||
cogl_framebuffer_draw_rectangle (pass->framebuffer,
|
||||
pass->pipeline,
|
||||
0, 0,
|
||||
cogl_texture_get_width (pass->texture),
|
||||
cogl_texture_get_height (pass->texture));
|
||||
}
|
||||
|
||||
static void
|
||||
clear_blur_pass (BlurPass *pass)
|
||||
{
|
||||
g_clear_object (&pass->pipeline);
|
||||
g_clear_object (&pass->texture);
|
||||
g_clear_object (&pass->framebuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_blur_new:
|
||||
* @texture: a #CoglTexture
|
||||
* @sigma: blur sigma
|
||||
*
|
||||
* Creates a new #ClutterBlur.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): A newly created #ClutterBlur
|
||||
*/
|
||||
ClutterBlur *
|
||||
clutter_blur_new (CoglTexture *texture,
|
||||
float radius)
|
||||
{
|
||||
ClutterBlur *blur;
|
||||
unsigned int height;
|
||||
unsigned int width;
|
||||
BlurPass *hpass;
|
||||
BlurPass *vpass;
|
||||
|
||||
g_return_val_if_fail (texture != NULL, NULL);
|
||||
g_return_val_if_fail (radius >= 0.0f, NULL);
|
||||
|
||||
width = cogl_texture_get_width (texture);
|
||||
height = cogl_texture_get_height (texture);
|
||||
|
||||
blur = g_new0 (ClutterBlur, 1);
|
||||
blur->sigma = radius / 2.0f;
|
||||
blur->source_texture = g_object_ref (texture);
|
||||
blur->downscale_factor = calculate_downscale_factor (width,
|
||||
height,
|
||||
blur->sigma);
|
||||
|
||||
if (G_APPROX_VALUE (blur->sigma, 0.0f, FLT_EPSILON))
|
||||
goto out;
|
||||
|
||||
vpass = &blur->pass[VERTICAL];
|
||||
hpass = &blur->pass[HORIZONTAL];
|
||||
|
||||
if (!setup_blur_pass (blur, vpass, VERTICAL, texture) ||
|
||||
!setup_blur_pass (blur, hpass, HORIZONTAL, vpass->texture))
|
||||
{
|
||||
clutter_blur_free (blur);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
return g_steal_pointer (&blur);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_blur_apply:
|
||||
* @blur: a #ClutterBlur
|
||||
*
|
||||
* Applies the blur. The resulting texture can be retrieved by
|
||||
* [method@Clutter.Blur.get_texture].
|
||||
*/
|
||||
void
|
||||
clutter_blur_apply (ClutterBlur *blur)
|
||||
{
|
||||
if (G_APPROX_VALUE (blur->sigma, 0.0, FLT_EPSILON))
|
||||
return;
|
||||
|
||||
apply_blur_pass (&blur->pass[VERTICAL]);
|
||||
apply_blur_pass (&blur->pass[HORIZONTAL]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_blur_get_texture:
|
||||
* @blur: a #ClutterBlur
|
||||
*
|
||||
* Retrieves the texture where the blurred contents are stored. The
|
||||
* contents are undefined until [method@Clutter.Blur.apply] is called.
|
||||
*
|
||||
* Returns: (transfer none): a #CoglTexture
|
||||
*/
|
||||
CoglTexture *
|
||||
clutter_blur_get_texture (ClutterBlur *blur)
|
||||
{
|
||||
if (G_APPROX_VALUE (blur->sigma, 0.0, FLT_EPSILON))
|
||||
return blur->source_texture;
|
||||
else
|
||||
return blur->pass[HORIZONTAL].texture;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_blur_free:
|
||||
* @blur: A #ClutterBlur
|
||||
*
|
||||
* Frees @blur.
|
||||
*/
|
||||
void
|
||||
clutter_blur_free (ClutterBlur *blur)
|
||||
{
|
||||
g_assert (blur);
|
||||
|
||||
clear_blur_pass (&blur->pass[VERTICAL]);
|
||||
clear_blur_pass (&blur->pass[HORIZONTAL]);
|
||||
g_clear_object (&blur->source_texture);
|
||||
g_free (blur);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,30 +25,61 @@
|
||||
* Thomas Wood <thomas.wood@intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_BOX_LAYOUT_H__
|
||||
#define __CLUTTER_BOX_LAYOUT_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-layout-manager.h"
|
||||
#include <clutter/clutter-layout-manager.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_BOX_LAYOUT (clutter_box_layout_get_type ())
|
||||
#define CLUTTER_BOX_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BOX_LAYOUT, ClutterBoxLayout))
|
||||
#define CLUTTER_IS_BOX_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BOX_LAYOUT))
|
||||
#define CLUTTER_BOX_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BOX_LAYOUT, ClutterBoxLayoutClass))
|
||||
#define CLUTTER_IS_BOX_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BOX_LAYOUT))
|
||||
#define CLUTTER_BOX_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BOX_LAYOUT, ClutterBoxLayoutClass))
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterBoxLayout,
|
||||
clutter_box_layout,
|
||||
CLUTTER, BOX_LAYOUT,
|
||||
ClutterLayoutManager)
|
||||
typedef struct _ClutterBoxLayout ClutterBoxLayout;
|
||||
typedef struct _ClutterBoxLayoutPrivate ClutterBoxLayoutPrivate;
|
||||
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
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterLayoutManager parent_instance;
|
||||
|
||||
ClutterBoxLayoutPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterBoxLayoutClass:
|
||||
*
|
||||
* The #ClutterBoxLayoutClass structure contains only private
|
||||
* data and should be accessed using the provided API
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
struct _ClutterBoxLayoutClass
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterLayoutManagerClass parent_class;
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_box_layout_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterLayoutManager * clutter_box_layout_new (void);
|
||||
|
||||
@@ -68,5 +99,70 @@ void clutter_box_layout_set_homogeneous (ClutterBoxLayou
|
||||
gboolean homogeneous);
|
||||
CLUTTER_EXPORT
|
||||
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
|
||||
|
||||
#endif /* __CLUTTER_BOX_LAYOUT_H__ */
|
||||
|
||||
@@ -23,26 +23,39 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterBrightnessContrastEffect:
|
||||
*
|
||||
* Increase/decrease brightness and/or contrast of actor.
|
||||
* SECTION:clutter-brightness-contrast-effect
|
||||
* @short_description: Increase/decrease brightness and/or contrast of actor.
|
||||
* @see_also: #ClutterEffect, #ClutterOffscreenEffect
|
||||
*
|
||||
* #ClutterBrightnessContrastEffect is a sub-class of #ClutterEffect that
|
||||
* changes the overall brightness of a #ClutterActor.
|
||||
*
|
||||
* #ClutterBrightnessContrastEffect is available since Clutter 1.10
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#define CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT, ClutterBrightnessContrastEffectClass))
|
||||
#define CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT))
|
||||
#define CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT, ClutterBrightnessContrastEffectClass))
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||
|
||||
#include "clutter/clutter-brightness-contrast-effect.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-enum-types.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#include "clutter-brightness-contrast-effect.h"
|
||||
|
||||
typedef struct _ClutterBrightnessContrastEffectPrivate
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-enum-types.h"
|
||||
#include "clutter-offscreen-effect.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
struct _ClutterBrightnessContrastEffect
|
||||
{
|
||||
ClutterOffscreenEffect parent_instance;
|
||||
|
||||
/* Brightness and contrast changes. */
|
||||
gfloat brightness_red;
|
||||
gfloat brightness_green;
|
||||
@@ -56,9 +69,18 @@ typedef struct _ClutterBrightnessContrastEffectPrivate
|
||||
gint brightness_offset_uniform;
|
||||
gint contrast_uniform;
|
||||
|
||||
CoglPipeline *pipeline;
|
||||
} ClutterBrightnessContrastEffectPrivate;
|
||||
gint tex_width;
|
||||
gint tex_height;
|
||||
|
||||
CoglPipeline *pipeline;
|
||||
};
|
||||
|
||||
struct _ClutterBrightnessContrastEffectClass
|
||||
{
|
||||
ClutterOffscreenEffectClass parent_class;
|
||||
|
||||
CoglPipeline *base_pipeline;
|
||||
};
|
||||
|
||||
/* Brightness effects in GLSL.
|
||||
*/
|
||||
@@ -76,8 +98,8 @@ static const gchar *brightness_contrast_source =
|
||||
"cogl_color_out.rgb = ((cogl_color_out.rgb - 0.5 * cogl_color_out.a) *\n"
|
||||
" contrast + 0.5 * cogl_color_out.a);\n";
|
||||
|
||||
static const CoglColor no_brightness_change = { 0x7f, 0x7f, 0x7f, 0xff };
|
||||
static const CoglColor no_contrast_change = { 0x7f, 0x7f, 0x7f, 0xff };
|
||||
static const ClutterColor no_brightness_change = { 0x7f, 0x7f, 0x7f, 0xff };
|
||||
static const ClutterColor no_contrast_change = { 0x7f, 0x7f, 0x7f, 0xff };
|
||||
static const gfloat no_change = 0.0f;
|
||||
|
||||
enum
|
||||
@@ -92,63 +114,99 @@ enum
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterBrightnessContrastEffect,
|
||||
clutter_brightness_contrast_effect,
|
||||
CLUTTER_TYPE_OFFSCREEN_EFFECT)
|
||||
G_DEFINE_TYPE (ClutterBrightnessContrastEffect,
|
||||
clutter_brightness_contrast_effect,
|
||||
CLUTTER_TYPE_OFFSCREEN_EFFECT);
|
||||
|
||||
static gboolean
|
||||
will_have_no_effect (ClutterBrightnessContrastEffect *self)
|
||||
{
|
||||
ClutterBrightnessContrastEffectPrivate *priv =
|
||||
clutter_brightness_contrast_effect_get_instance_private (self);
|
||||
|
||||
return (G_APPROX_VALUE (priv->brightness_red, no_change, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (priv->brightness_green, no_change, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (priv->brightness_blue, no_change, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (priv->contrast_red, no_change, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (priv->contrast_green, no_change, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (priv->contrast_blue, no_change, FLT_EPSILON));
|
||||
}
|
||||
|
||||
static CoglPipeline *
|
||||
clutter_brightness_contrast_effect_create_pipeline (ClutterOffscreenEffect *effect,
|
||||
CoglTexture *texture)
|
||||
{
|
||||
ClutterBrightnessContrastEffect *self =
|
||||
CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
|
||||
ClutterBrightnessContrastEffectPrivate *priv =
|
||||
clutter_brightness_contrast_effect_get_instance_private (self);
|
||||
|
||||
cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture);
|
||||
|
||||
return g_object_ref (priv->pipeline);
|
||||
return (self->brightness_red == no_change &&
|
||||
self->brightness_green == no_change &&
|
||||
self->brightness_blue == no_change &&
|
||||
self->contrast_red == no_change &&
|
||||
self->contrast_green == no_change &&
|
||||
self->contrast_blue == no_change);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context)
|
||||
clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect)
|
||||
{
|
||||
ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
|
||||
ClutterEffectClass *parent_class;
|
||||
|
||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
|
||||
return FALSE;
|
||||
|
||||
if (will_have_no_effect (self))
|
||||
return FALSE;
|
||||
|
||||
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 =
|
||||
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
|
||||
clutter_brightness_contrast_effect_dispose (GObject *gobject)
|
||||
{
|
||||
ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (gobject);
|
||||
ClutterBrightnessContrastEffectPrivate *priv =
|
||||
clutter_brightness_contrast_effect_get_instance_private (self);
|
||||
|
||||
g_clear_object (&priv->pipeline);
|
||||
if (self->pipeline != NULL)
|
||||
{
|
||||
cogl_object_unref (self->pipeline);
|
||||
self->pipeline = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (clutter_brightness_contrast_effect_parent_class)->dispose (gobject);
|
||||
}
|
||||
@@ -165,7 +223,7 @@ clutter_brightness_contrast_effect_set_property (GObject *gobject,
|
||||
{
|
||||
case PROP_BRIGHTNESS:
|
||||
{
|
||||
const CoglColor *color = cogl_value_get_color (value);
|
||||
const ClutterColor *color = clutter_value_get_color (value);
|
||||
clutter_brightness_contrast_effect_set_brightness_full (effect,
|
||||
color->red / 127.0f - 1.0f,
|
||||
color->green / 127.0f - 1.0f,
|
||||
@@ -175,7 +233,7 @@ clutter_brightness_contrast_effect_set_property (GObject *gobject,
|
||||
|
||||
case PROP_CONTRAST:
|
||||
{
|
||||
const CoglColor *color = cogl_value_get_color (value);
|
||||
const ClutterColor *color = clutter_value_get_color (value);
|
||||
clutter_brightness_contrast_effect_set_contrast_full (effect,
|
||||
color->red / 127.0f - 1.0f,
|
||||
color->green / 127.0f - 1.0f,
|
||||
@@ -196,31 +254,29 @@ clutter_brightness_contrast_effect_get_property (GObject *gobject,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterBrightnessContrastEffect *effect = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (gobject);
|
||||
ClutterBrightnessContrastEffectPrivate *priv =
|
||||
clutter_brightness_contrast_effect_get_instance_private (effect);
|
||||
CoglColor color;
|
||||
ClutterColor color;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_BRIGHTNESS:
|
||||
{
|
||||
color.red = (uint8_t) ((priv->brightness_red + 1.0f) * 127.0f);
|
||||
color.green = (uint8_t) ((priv->brightness_green + 1.0f) * 127.0f);
|
||||
color.blue = (uint8_t) ((priv->brightness_blue + 1.0f) * 127.0f);
|
||||
color.red = (effect->brightness_red + 1.0f) * 127.0f;
|
||||
color.green = (effect->brightness_green + 1.0f) * 127.0f;
|
||||
color.blue = (effect->brightness_blue + 1.0f) * 127.0f;
|
||||
color.alpha = 0xff;
|
||||
|
||||
cogl_value_set_color (value, &color);
|
||||
clutter_value_set_color (value, &color);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_CONTRAST:
|
||||
{
|
||||
color.red = (uint8_t) ((priv->contrast_red + 1.0f) * 127.0f);
|
||||
color.green = (uint8_t) ((priv->contrast_green + 1.0f) * 127.0f);
|
||||
color.blue = (uint8_t) ((priv->contrast_blue + 1.0f) * 127.0f);
|
||||
color.red = (effect->contrast_red + 1.0f) * 127.0f;
|
||||
color.green = (effect->contrast_green + 1.0f) * 127.0f;
|
||||
color.blue = (effect->contrast_blue + 1.0f) * 127.0f;
|
||||
color.alpha = 0xff;
|
||||
|
||||
cogl_value_set_color (value, &color);
|
||||
clutter_value_set_color (value, &color);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -238,7 +294,7 @@ clutter_brightness_contrast_effect_class_init (ClutterBrightnessContrastEffectCl
|
||||
ClutterOffscreenEffectClass *offscreen_class;
|
||||
|
||||
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
||||
offscreen_class->create_pipeline = clutter_brightness_contrast_effect_create_pipeline;
|
||||
offscreen_class->paint_target = clutter_brightness_contrast_effect_paint_target;
|
||||
|
||||
effect_class->pre_paint = clutter_brightness_contrast_effect_pre_paint;
|
||||
|
||||
@@ -251,34 +307,40 @@ clutter_brightness_contrast_effect_class_init (ClutterBrightnessContrastEffectCl
|
||||
*
|
||||
* The brightness change to apply to the effect.
|
||||
*
|
||||
* This property uses a #CoglColor to represent the changes to each
|
||||
* This property uses a #ClutterColor to represent the changes to each
|
||||
* color channel. The range is [ 0, 255 ], with 127 as the value used
|
||||
* to indicate no change; values smaller than 127 indicate a decrease
|
||||
* in brightness, and values larger than 127 indicate an increase in
|
||||
* brightness.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
obj_props[PROP_BRIGHTNESS] =
|
||||
cogl_param_spec_color ("brightness", NULL, NULL,
|
||||
&no_brightness_change,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
clutter_param_spec_color ("brightness",
|
||||
P_("Brightness"),
|
||||
P_("The brightness change to apply"),
|
||||
&no_brightness_change,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* ClutterBrightnessContrastEffect:contrast:
|
||||
*
|
||||
* The contrast change to apply to the effect.
|
||||
*
|
||||
* This property uses a #CoglColor to represent the changes to each
|
||||
* This property uses a #ClutterColor to represent the changes to each
|
||||
* color channel. The range is [ 0, 255 ], with 127 as the value used
|
||||
* to indicate no change; values smaller than 127 indicate a decrease
|
||||
* in contrast, and values larger than 127 indicate an increase in
|
||||
* contrast.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
obj_props[PROP_CONTRAST] =
|
||||
cogl_param_spec_color ("contrast", NULL, NULL,
|
||||
&no_contrast_change,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
clutter_param_spec_color ("contrast",
|
||||
P_("Contrast"),
|
||||
P_("The contrast change to apply"),
|
||||
&no_contrast_change,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
|
||||
}
|
||||
@@ -303,47 +365,44 @@ get_brightness_values (gfloat value,
|
||||
static inline void
|
||||
update_uniforms (ClutterBrightnessContrastEffect *self)
|
||||
{
|
||||
ClutterBrightnessContrastEffectPrivate *priv =
|
||||
clutter_brightness_contrast_effect_get_instance_private (self);
|
||||
|
||||
if (priv->brightness_multiplier_uniform > -1 &&
|
||||
priv->brightness_offset_uniform > -1)
|
||||
if (self->brightness_multiplier_uniform > -1 &&
|
||||
self->brightness_offset_uniform > -1)
|
||||
{
|
||||
float brightness_multiplier[3];
|
||||
float brightness_offset[3];
|
||||
|
||||
get_brightness_values (priv->brightness_red,
|
||||
get_brightness_values (self->brightness_red,
|
||||
brightness_multiplier + 0,
|
||||
brightness_offset + 0);
|
||||
get_brightness_values (priv->brightness_green,
|
||||
get_brightness_values (self->brightness_green,
|
||||
brightness_multiplier + 1,
|
||||
brightness_offset + 1);
|
||||
get_brightness_values (priv->brightness_blue,
|
||||
get_brightness_values (self->brightness_blue,
|
||||
brightness_multiplier + 2,
|
||||
brightness_offset + 2);
|
||||
|
||||
cogl_pipeline_set_uniform_float (priv->pipeline,
|
||||
priv->brightness_multiplier_uniform,
|
||||
cogl_pipeline_set_uniform_float (self->pipeline,
|
||||
self->brightness_multiplier_uniform,
|
||||
3, /* n_components */
|
||||
1, /* count */
|
||||
brightness_multiplier);
|
||||
cogl_pipeline_set_uniform_float (priv->pipeline,
|
||||
priv->brightness_offset_uniform,
|
||||
cogl_pipeline_set_uniform_float (self->pipeline,
|
||||
self->brightness_offset_uniform,
|
||||
3, /* n_components */
|
||||
1, /* count */
|
||||
brightness_offset);
|
||||
}
|
||||
|
||||
if (priv->contrast_uniform > -1)
|
||||
if (self->contrast_uniform > -1)
|
||||
{
|
||||
float contrast[3] = {
|
||||
(float) tan ((priv->contrast_red + 1) * G_PI_4),
|
||||
(float) tan ((priv->contrast_green + 1) * G_PI_4),
|
||||
(float) tan ((priv->contrast_blue + 1) * G_PI_4)
|
||||
tan ((self->contrast_red + 1) * G_PI_4),
|
||||
tan ((self->contrast_green + 1) * G_PI_4),
|
||||
tan ((self->contrast_blue + 1) * G_PI_4)
|
||||
};
|
||||
|
||||
cogl_pipeline_set_uniform_float (priv->pipeline,
|
||||
priv->contrast_uniform,
|
||||
cogl_pipeline_set_uniform_float (self->pipeline,
|
||||
self->contrast_uniform,
|
||||
3, /* n_components */
|
||||
1, /* count */
|
||||
contrast);
|
||||
@@ -354,49 +413,44 @@ static void
|
||||
clutter_brightness_contrast_effect_init (ClutterBrightnessContrastEffect *self)
|
||||
{
|
||||
ClutterBrightnessContrastEffectClass *klass;
|
||||
ClutterBrightnessContrastEffectPrivate *priv =
|
||||
clutter_brightness_contrast_effect_get_instance_private (self);
|
||||
|
||||
priv->brightness_red = no_change;
|
||||
priv->brightness_green = no_change;
|
||||
priv->brightness_blue = no_change;
|
||||
self->brightness_red = no_change;
|
||||
self->brightness_green = no_change;
|
||||
self->brightness_blue = no_change;
|
||||
|
||||
priv->contrast_red = no_change;
|
||||
priv->contrast_green = no_change;
|
||||
priv->contrast_blue = no_change;
|
||||
self->contrast_red = no_change;
|
||||
self->contrast_green = no_change;
|
||||
self->contrast_blue = no_change;
|
||||
|
||||
klass = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_GET_CLASS (self);
|
||||
|
||||
if (G_UNLIKELY (klass->base_pipeline == NULL))
|
||||
{
|
||||
CoglSnippet *snippet;
|
||||
ClutterContext *context = _clutter_context_get_default ();
|
||||
ClutterBackend *backend = clutter_context_get_backend (context);
|
||||
CoglContext *cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
CoglContext *ctx =
|
||||
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
|
||||
klass->base_pipeline = cogl_pipeline_new (cogl_context);
|
||||
cogl_pipeline_set_static_name (klass->base_pipeline,
|
||||
"ClutterBrightnessContrast");
|
||||
klass->base_pipeline = cogl_pipeline_new (ctx);
|
||||
|
||||
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
|
||||
brightness_contrast_decls,
|
||||
brightness_contrast_source);
|
||||
cogl_pipeline_add_snippet (klass->base_pipeline, snippet);
|
||||
g_object_unref (snippet);
|
||||
cogl_object_unref (snippet);
|
||||
|
||||
cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0);
|
||||
}
|
||||
|
||||
priv->pipeline = cogl_pipeline_copy (klass->base_pipeline);
|
||||
self->pipeline = cogl_pipeline_copy (klass->base_pipeline);
|
||||
|
||||
priv->brightness_multiplier_uniform =
|
||||
cogl_pipeline_get_uniform_location (priv->pipeline,
|
||||
self->brightness_multiplier_uniform =
|
||||
cogl_pipeline_get_uniform_location (self->pipeline,
|
||||
"brightness_multiplier");
|
||||
priv->brightness_offset_uniform =
|
||||
cogl_pipeline_get_uniform_location (priv->pipeline,
|
||||
self->brightness_offset_uniform =
|
||||
cogl_pipeline_get_uniform_location (self->pipeline,
|
||||
"brightness_offset");
|
||||
priv->contrast_uniform =
|
||||
cogl_pipeline_get_uniform_location (priv->pipeline, "contrast");
|
||||
self->contrast_uniform =
|
||||
cogl_pipeline_get_uniform_location (self->pipeline, "contrast");
|
||||
|
||||
update_uniforms (self);
|
||||
}
|
||||
@@ -405,11 +459,13 @@ clutter_brightness_contrast_effect_init (ClutterBrightnessContrastEffect *self)
|
||||
* clutter_brightness_contrast_effect_new:
|
||||
*
|
||||
* Creates a new #ClutterBrightnessContrastEffect to be used with
|
||||
* [method@Clutter.Actor.add_effect]
|
||||
* clutter_actor_add_effect()
|
||||
*
|
||||
* Return value: (transfer full): the newly created
|
||||
* #ClutterBrightnessContrastEffect or %NULL. Use g_object_unref() when
|
||||
* done.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
ClutterEffect *
|
||||
clutter_brightness_contrast_effect_new (void)
|
||||
@@ -427,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,
|
||||
* values below 0.0 mean a decrease in brightness, and values above indicate
|
||||
* an increase.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
void
|
||||
clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContrastEffect *effect,
|
||||
@@ -434,19 +492,16 @@ clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContras
|
||||
gfloat green,
|
||||
gfloat blue)
|
||||
{
|
||||
ClutterBrightnessContrastEffectPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
|
||||
|
||||
priv = clutter_brightness_contrast_effect_get_instance_private (effect);
|
||||
if (G_APPROX_VALUE (red, priv->brightness_red, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (green, priv->brightness_green, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (blue, priv->brightness_blue, FLT_EPSILON))
|
||||
if (red == effect->brightness_red &&
|
||||
green == effect->brightness_green &&
|
||||
blue == effect->brightness_blue)
|
||||
return;
|
||||
|
||||
priv->brightness_red = red;
|
||||
priv->brightness_green = green;
|
||||
priv->brightness_blue = blue;
|
||||
effect->brightness_red = red;
|
||||
effect->brightness_green = green;
|
||||
effect->brightness_blue = blue;
|
||||
|
||||
update_uniforms (effect);
|
||||
|
||||
@@ -466,6 +521,8 @@ clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContras
|
||||
* change in brightness
|
||||
*
|
||||
* Retrieves the change in brightness used by @effect.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
void
|
||||
clutter_brightness_contrast_effect_get_brightness (ClutterBrightnessContrastEffect *effect,
|
||||
@@ -473,19 +530,16 @@ clutter_brightness_contrast_effect_get_brightness (ClutterBrightnessContrastEffe
|
||||
gfloat *green,
|
||||
gfloat *blue)
|
||||
{
|
||||
ClutterBrightnessContrastEffectPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
|
||||
|
||||
priv = clutter_brightness_contrast_effect_get_instance_private (effect);
|
||||
if (red != NULL)
|
||||
*red = priv->brightness_red;
|
||||
*red = effect->brightness_red;
|
||||
|
||||
if (green != NULL)
|
||||
*green = priv->brightness_green;
|
||||
*green = effect->brightness_green;
|
||||
|
||||
if (blue != NULL)
|
||||
*blue = priv->brightness_blue;
|
||||
*blue = effect->brightness_blue;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -496,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;
|
||||
* a value below 0.0 indicates a decrease in brightness; and a value
|
||||
* above 0.0 indicates an increase of brightness.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
void
|
||||
clutter_brightness_contrast_effect_set_brightness (ClutterBrightnessContrastEffect *effect,
|
||||
@@ -517,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,
|
||||
* values below 0.0 mean a decrease in contrast, and values above indicate
|
||||
* an increase.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
void
|
||||
clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastEffect *effect,
|
||||
@@ -524,19 +582,16 @@ clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastE
|
||||
gfloat green,
|
||||
gfloat blue)
|
||||
{
|
||||
ClutterBrightnessContrastEffectPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
|
||||
|
||||
priv = clutter_brightness_contrast_effect_get_instance_private (effect);
|
||||
if (G_APPROX_VALUE (red, priv->contrast_red, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (green, priv->contrast_green, FLT_EPSILON) &&
|
||||
G_APPROX_VALUE (blue, priv->contrast_blue, FLT_EPSILON))
|
||||
if (red == effect->contrast_red &&
|
||||
green == effect->contrast_green &&
|
||||
blue == effect->contrast_blue)
|
||||
return;
|
||||
|
||||
priv->contrast_red = red;
|
||||
priv->contrast_green = green;
|
||||
priv->contrast_blue = blue;
|
||||
effect->contrast_red = red;
|
||||
effect->contrast_green = green;
|
||||
effect->contrast_blue = blue;
|
||||
|
||||
update_uniforms (effect);
|
||||
|
||||
@@ -556,6 +611,8 @@ clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastE
|
||||
* change in contrast
|
||||
*
|
||||
* Retrieves the contrast value used by @effect.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
void
|
||||
clutter_brightness_contrast_effect_get_contrast (ClutterBrightnessContrastEffect *effect,
|
||||
@@ -563,19 +620,16 @@ clutter_brightness_contrast_effect_get_contrast (ClutterBrightnessContrastEffect
|
||||
gfloat *green,
|
||||
gfloat *blue)
|
||||
{
|
||||
ClutterBrightnessContrastEffectPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect));
|
||||
|
||||
priv = clutter_brightness_contrast_effect_get_instance_private (effect);
|
||||
if (red != NULL)
|
||||
*red = priv->contrast_red;
|
||||
*red = effect->contrast_red;
|
||||
|
||||
if (green != NULL)
|
||||
*green = priv->contrast_green;
|
||||
*green = effect->contrast_green;
|
||||
|
||||
if (blue != NULL)
|
||||
*blue = priv->contrast_blue;
|
||||
*blue = effect->contrast_blue;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -586,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;
|
||||
* a value below 0.0 indicates a decrease in contrast; and a value above
|
||||
* 0.0 indicates an increase.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
void
|
||||
clutter_brightness_contrast_effect_set_contrast (ClutterBrightnessContrastEffect *effect,
|
||||
|
||||
@@ -22,32 +22,35 @@
|
||||
* Joseph Scheuhammer <clown@alum.mit.edu>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_H__
|
||||
#define __CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-effect.h"
|
||||
#include "clutter/clutter-offscreen-effect.h"
|
||||
#include <clutter/clutter-color.h>
|
||||
#include <clutter/clutter-effect.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT (clutter_brightness_contrast_effect_get_type ())
|
||||
#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))
|
||||
|
||||
|
||||
struct _ClutterBrightnessContrastEffectClass
|
||||
{
|
||||
ClutterOffscreenEffectClass parent_class;
|
||||
|
||||
CoglPipeline *base_pipeline;
|
||||
};
|
||||
/**
|
||||
* ClutterBrightnessContrastEffect:
|
||||
*
|
||||
* #ClutterBrightnessContrastEffect is an opaque structure
|
||||
* whose members cannot be directly accessed
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
typedef struct _ClutterBrightnessContrastEffect ClutterBrightnessContrastEffect;
|
||||
typedef struct _ClutterBrightnessContrastEffectClass ClutterBrightnessContrastEffectClass;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterBrightnessContrastEffect,
|
||||
clutter_brightness_contrast_effect,
|
||||
CLUTTER, BRIGHTNESS_CONTRAST_EFFECT,
|
||||
ClutterOffscreenEffect)
|
||||
GType clutter_brightness_contrast_effect_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterEffect * clutter_brightness_contrast_effect_new (void);
|
||||
@@ -81,3 +84,5 @@ void clutter_brightness_contrast_effect_get_contrast
|
||||
float *blue);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_H__ */
|
||||
|
||||
14
clutter/clutter/clutter-build-config.h.meson
Normal file
14
clutter/clutter/clutter-build-config.h.meson
Normal file
@@ -0,0 +1,14 @@
|
||||
/* Mutter version */
|
||||
#mesondefine MUTTER_VERSION
|
||||
|
||||
/* List of Cogl drivers */
|
||||
#mesondefine CLUTTER_DRIVERS
|
||||
|
||||
/* Have evdev support for input handling */
|
||||
#mesondefine HAVE_EVDEV
|
||||
|
||||
/* Building with libwacom for advanced tablet management */
|
||||
#mesondefine HAVE_LIBWACOM
|
||||
|
||||
/* Supports PangoFt2 */
|
||||
#mesondefine HAVE_PANGO_FT2
|
||||
90
clutter/clutter/clutter-cairo.c
Normal file
90
clutter/clutter/clutter-cairo.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2012 Intel Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:clutter-cairo
|
||||
* @Title: Cairo integration
|
||||
* @Short_Description: Functions for interoperating with Cairo
|
||||
*
|
||||
* Clutter provides some utility functions for using Cairo.
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter-cairo.h"
|
||||
#include "clutter-color.h"
|
||||
|
||||
/**
|
||||
* clutter_cairo_set_source_color:
|
||||
* @cr: a Cairo context
|
||||
* @color: a #ClutterColor
|
||||
*
|
||||
* Utility function for setting the source color of @cr using
|
||||
* a #ClutterColor. This function is the equivalent of:
|
||||
*
|
||||
* |[
|
||||
* cairo_set_source_rgba (cr,
|
||||
* color->red / 255.0,
|
||||
* color->green / 255.0,
|
||||
* color->blue / 255.0,
|
||||
* color->alpha / 255.0);
|
||||
* ]|
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_cairo_set_source_color (cairo_t *cr,
|
||||
const ClutterColor *color)
|
||||
{
|
||||
g_return_if_fail (cr != NULL);
|
||||
g_return_if_fail (color != NULL);
|
||||
|
||||
if (color->alpha == 0xff)
|
||||
cairo_set_source_rgb (cr,
|
||||
color->red / 255.0,
|
||||
color->green / 255.0,
|
||||
color->blue / 255.0);
|
||||
else
|
||||
cairo_set_source_rgba (cr,
|
||||
color->red / 255.0,
|
||||
color->green / 255.0,
|
||||
color->blue / 255.0,
|
||||
color->alpha / 255.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_cairo_clear:
|
||||
* @cr: a Cairo context
|
||||
*
|
||||
* Utility function to clear a Cairo context.
|
||||
*
|
||||
* Since: 1.12
|
||||
*/
|
||||
void
|
||||
clutter_cairo_clear (cairo_t *cr)
|
||||
{
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
61
clutter/clutter/clutter-cairo.h
Normal file
61
clutter/clutter/clutter-cairo.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2012 Intel Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_CAIRO_H__
|
||||
#define __CLUTTER_CAIRO_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <clutter/clutter-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* CLUTTER_CAIRO_FORMAT_ARGB32:
|
||||
*
|
||||
* The #CoglPixelFormat to be used when uploading image data from
|
||||
* and to a Cairo image surface using %CAIRO_FORMAT_ARGB32 and
|
||||
* %CAIRO_FORMAT_RGB24 as #cairo_format_t.
|
||||
*
|
||||
* Since: 1.8
|
||||
*/
|
||||
|
||||
/* Cairo stores the data in native byte order as ARGB but Cogl's pixel
|
||||
* formats specify the actual byte order. Therefore we need to use a
|
||||
* different format depending on the architecture
|
||||
*/
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
#define CLUTTER_CAIRO_FORMAT_ARGB32 (COGL_PIXEL_FORMAT_BGRA_8888_PRE)
|
||||
#else
|
||||
#define CLUTTER_CAIRO_FORMAT_ARGB32 (COGL_PIXEL_FORMAT_ARGB_8888_PRE)
|
||||
#endif
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_cairo_clear (cairo_t *cr);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_cairo_set_source_color (cairo_t *cr,
|
||||
const ClutterColor *color);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_CAIRO_H__ */
|
||||
645
clutter/clutter/clutter-canvas.c
Normal file
645
clutter/clutter/clutter-canvas.c
Normal file
@@ -0,0 +1,645 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2012 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:clutter-canvas
|
||||
* @Title: ClutterCanvas
|
||||
* @Short_Description: Content for 2D painting
|
||||
* @See_Also: #ClutterContent
|
||||
*
|
||||
* The #ClutterCanvas class is a #ClutterContent implementation that allows
|
||||
* drawing using the Cairo API on a 2D surface.
|
||||
*
|
||||
* In order to draw on a #ClutterCanvas, you should connect a handler to the
|
||||
* #ClutterCanvas::draw signal; the signal will receive a #cairo_t context
|
||||
* that can be used to draw. #ClutterCanvas will emit the #ClutterCanvas::draw
|
||||
* signal when invalidated using clutter_content_invalidate().
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* #ClutterCanvas is available since Clutter 1.10.
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <cairo-gobject.h>
|
||||
|
||||
#include "clutter-canvas.h"
|
||||
|
||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||
|
||||
#include "clutter-actor-private.h"
|
||||
#include "clutter-backend.h"
|
||||
#include "clutter-cairo.h"
|
||||
#include "clutter-color.h"
|
||||
#include "clutter-content-private.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-marshal.h"
|
||||
#include "clutter-paint-node.h"
|
||||
#include "clutter-paint-nodes.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-settings.h"
|
||||
|
||||
struct _ClutterCanvasPrivate
|
||||
{
|
||||
cairo_t *cr;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
float scale_factor;
|
||||
|
||||
CoglTexture *texture;
|
||||
gboolean dirty;
|
||||
|
||||
CoglBitmap *buffer;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_WIDTH,
|
||||
PROP_HEIGHT,
|
||||
PROP_SCALE_FACTOR,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[LAST_PROP] = { NULL, };
|
||||
|
||||
enum
|
||||
{
|
||||
DRAW,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint canvas_signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
static void clutter_content_iface_init (ClutterContentInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (ClutterCanvas, clutter_canvas, G_TYPE_OBJECT,
|
||||
G_ADD_PRIVATE (ClutterCanvas)
|
||||
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT,
|
||||
clutter_content_iface_init))
|
||||
|
||||
static void
|
||||
clutter_cairo_context_draw_marshaller (GClosure *closure,
|
||||
GValue *return_value,
|
||||
guint n_param_values,
|
||||
const GValue *param_values,
|
||||
gpointer invocation_hint,
|
||||
gpointer marshal_data)
|
||||
{
|
||||
cairo_t *cr = g_value_get_boxed (¶m_values[1]);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
_clutter_marshal_BOOLEAN__BOXED_INT_INT (closure,
|
||||
return_value,
|
||||
n_param_values,
|
||||
param_values,
|
||||
invocation_hint,
|
||||
marshal_data);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_canvas_finalize (GObject *gobject)
|
||||
{
|
||||
ClutterCanvasPrivate *priv = CLUTTER_CANVAS (gobject)->priv;
|
||||
|
||||
if (priv->buffer != NULL)
|
||||
{
|
||||
cogl_object_unref (priv->buffer);
|
||||
priv->buffer = NULL;
|
||||
}
|
||||
|
||||
g_clear_pointer (&priv->texture, cogl_object_unref);
|
||||
|
||||
G_OBJECT_CLASS (clutter_canvas_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_canvas_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterCanvasPrivate *priv = CLUTTER_CANVAS (gobject)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_WIDTH:
|
||||
{
|
||||
gint new_size = g_value_get_int (value);
|
||||
|
||||
if (priv->width != new_size)
|
||||
{
|
||||
priv->width = new_size;
|
||||
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (gobject));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_HEIGHT:
|
||||
{
|
||||
gint new_size = g_value_get_int (value);
|
||||
|
||||
if (priv->height != new_size)
|
||||
{
|
||||
priv->height = new_size;
|
||||
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (gobject));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_SCALE_FACTOR:
|
||||
{
|
||||
gfloat new_scale_factor = g_value_get_float (value);
|
||||
|
||||
if (priv->scale_factor != new_scale_factor)
|
||||
{
|
||||
priv->scale_factor = new_scale_factor;
|
||||
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (gobject));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_canvas_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterCanvasPrivate *priv = CLUTTER_CANVAS (gobject)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_WIDTH:
|
||||
g_value_set_int (value, priv->width);
|
||||
break;
|
||||
|
||||
case PROP_HEIGHT:
|
||||
g_value_set_int (value, priv->height);
|
||||
break;
|
||||
|
||||
case PROP_SCALE_FACTOR:
|
||||
g_value_set_float (value, priv->scale_factor);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_canvas_class_init (ClutterCanvasClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
/**
|
||||
* ClutterCanvas:width:
|
||||
*
|
||||
* The width of the canvas.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
obj_props[PROP_WIDTH] =
|
||||
g_param_spec_int ("width",
|
||||
P_("Width"),
|
||||
P_("The width of the canvas"),
|
||||
-1, G_MAXINT,
|
||||
-1,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterCanvas:height:
|
||||
*
|
||||
* The height of the canvas.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
obj_props[PROP_HEIGHT] =
|
||||
g_param_spec_int ("height",
|
||||
P_("Height"),
|
||||
P_("The height of the canvas"),
|
||||
-1, G_MAXINT,
|
||||
-1,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterCanvas:scale-factor:
|
||||
*
|
||||
* The height of the canvas.
|
||||
*/
|
||||
obj_props[PROP_SCALE_FACTOR] =
|
||||
g_param_spec_float ("scale-factor",
|
||||
P_("Scale Factor"),
|
||||
P_("The Scale factor of the canvas"),
|
||||
0.01f, G_MAXFLOAT,
|
||||
1.0f,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterCanvas::draw:
|
||||
* @canvas: the #ClutterCanvas that emitted the signal
|
||||
* @cr: the Cairo context used to draw
|
||||
* @width: the width of the @canvas
|
||||
* @height: the height of the @canvas
|
||||
*
|
||||
* The #ClutterCanvas::draw signal is emitted each time a canvas is
|
||||
* invalidated.
|
||||
*
|
||||
* It is safe to connect multiple handlers to this signal: each
|
||||
* handler invocation will be automatically protected by cairo_save()
|
||||
* and cairo_restore() pairs.
|
||||
*
|
||||
* Return value: %TRUE if the signal emission should stop, and
|
||||
* %FALSE otherwise
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
canvas_signals[DRAW] =
|
||||
g_signal_new (I_("draw"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
|
||||
G_STRUCT_OFFSET (ClutterCanvasClass, draw),
|
||||
_clutter_boolean_handled_accumulator, NULL,
|
||||
clutter_cairo_context_draw_marshaller,
|
||||
G_TYPE_BOOLEAN, 3,
|
||||
CAIRO_GOBJECT_TYPE_CONTEXT,
|
||||
G_TYPE_INT,
|
||||
G_TYPE_INT);
|
||||
|
||||
gobject_class->set_property = clutter_canvas_set_property;
|
||||
gobject_class->get_property = clutter_canvas_get_property;
|
||||
gobject_class->finalize = clutter_canvas_finalize;
|
||||
|
||||
g_object_class_install_properties (gobject_class, LAST_PROP, obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_canvas_init (ClutterCanvas *self)
|
||||
{
|
||||
self->priv = clutter_canvas_get_instance_private (self);
|
||||
|
||||
self->priv->width = -1;
|
||||
self->priv->height = -1;
|
||||
self->priv->scale_factor = 1.0f;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_canvas_paint_content (ClutterContent *content,
|
||||
ClutterActor *actor,
|
||||
ClutterPaintNode *root)
|
||||
{
|
||||
ClutterCanvas *self = CLUTTER_CANVAS (content);
|
||||
ClutterCanvasPrivate *priv = self->priv;
|
||||
ClutterPaintNode *node;
|
||||
|
||||
if (priv->buffer == NULL)
|
||||
return;
|
||||
|
||||
if (priv->dirty)
|
||||
g_clear_pointer (&priv->texture, cogl_object_unref);
|
||||
|
||||
if (priv->texture == NULL)
|
||||
priv->texture = cogl_texture_new_from_bitmap (priv->buffer,
|
||||
COGL_TEXTURE_NO_SLICING,
|
||||
CLUTTER_CAIRO_FORMAT_ARGB32);
|
||||
|
||||
if (priv->texture == NULL)
|
||||
return;
|
||||
|
||||
node = clutter_actor_create_texture_paint_node (actor, priv->texture);
|
||||
clutter_paint_node_set_name (node, "Canvas Content");
|
||||
clutter_paint_node_add_child (root, node);
|
||||
clutter_paint_node_unref (node);
|
||||
|
||||
priv->dirty = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_canvas_emit_draw (ClutterCanvas *self)
|
||||
{
|
||||
ClutterCanvasPrivate *priv = self->priv;
|
||||
int real_width, real_height;
|
||||
cairo_surface_t *surface;
|
||||
gboolean mapped_buffer;
|
||||
unsigned char *data;
|
||||
CoglBuffer *buffer;
|
||||
gboolean res;
|
||||
cairo_t *cr;
|
||||
|
||||
g_assert (priv->height > 0 && priv->width > 0);
|
||||
|
||||
priv->dirty = TRUE;
|
||||
|
||||
real_width = ceilf (priv->width * priv->scale_factor);
|
||||
real_height = ceilf (priv->height * priv->scale_factor);
|
||||
|
||||
CLUTTER_NOTE (MISC, "Creating Cairo surface with size %d x %d",
|
||||
priv->width, priv->height);
|
||||
|
||||
if (priv->buffer == NULL)
|
||||
{
|
||||
CoglContext *ctx;
|
||||
|
||||
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
priv->buffer = cogl_bitmap_new_with_size (ctx,
|
||||
real_width,
|
||||
real_height,
|
||||
CLUTTER_CAIRO_FORMAT_ARGB32);
|
||||
}
|
||||
|
||||
buffer = COGL_BUFFER (cogl_bitmap_get_buffer (priv->buffer));
|
||||
if (buffer == NULL)
|
||||
return;
|
||||
|
||||
cogl_buffer_set_update_hint (buffer, COGL_BUFFER_UPDATE_HINT_DYNAMIC);
|
||||
|
||||
data = cogl_buffer_map (buffer,
|
||||
COGL_BUFFER_ACCESS_READ_WRITE,
|
||||
COGL_BUFFER_MAP_HINT_DISCARD);
|
||||
|
||||
if (data != NULL)
|
||||
{
|
||||
int bitmap_stride = cogl_bitmap_get_rowstride (priv->buffer);
|
||||
|
||||
surface = cairo_image_surface_create_for_data (data,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
real_width,
|
||||
real_height,
|
||||
bitmap_stride);
|
||||
mapped_buffer = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
real_width,
|
||||
real_height);
|
||||
|
||||
mapped_buffer = FALSE;
|
||||
}
|
||||
|
||||
cairo_surface_set_device_scale (surface,
|
||||
priv->scale_factor,
|
||||
priv->scale_factor);
|
||||
|
||||
self->priv->cr = cr = cairo_create (surface);
|
||||
|
||||
g_signal_emit (self, canvas_signals[DRAW], 0,
|
||||
cr, priv->width, priv->height,
|
||||
&res);
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
if (_clutter_diagnostic_enabled () && cairo_status (cr))
|
||||
{
|
||||
g_warning ("Drawing failed for <ClutterCanvas>[%p]: %s",
|
||||
self,
|
||||
cairo_status_to_string (cairo_status (cr)));
|
||||
}
|
||||
#endif
|
||||
|
||||
self->priv->cr = NULL;
|
||||
cairo_destroy (cr);
|
||||
|
||||
if (mapped_buffer)
|
||||
cogl_buffer_unmap (buffer);
|
||||
else
|
||||
{
|
||||
int size = cairo_image_surface_get_stride (surface) * priv->height;
|
||||
cogl_buffer_set_data (buffer,
|
||||
0,
|
||||
cairo_image_surface_get_data (surface),
|
||||
size);
|
||||
}
|
||||
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_canvas_invalidate (ClutterContent *content)
|
||||
{
|
||||
ClutterCanvas *self = CLUTTER_CANVAS (content);
|
||||
ClutterCanvasPrivate *priv = self->priv;
|
||||
|
||||
if (priv->buffer != NULL)
|
||||
{
|
||||
cogl_object_unref (priv->buffer);
|
||||
priv->buffer = NULL;
|
||||
}
|
||||
|
||||
if (priv->width <= 0 || priv->height <= 0)
|
||||
return;
|
||||
|
||||
clutter_canvas_emit_draw (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_canvas_get_preferred_size (ClutterContent *content,
|
||||
gfloat *width,
|
||||
gfloat *height)
|
||||
{
|
||||
ClutterCanvasPrivate *priv = CLUTTER_CANVAS (content)->priv;
|
||||
|
||||
if (priv->width < 0 || priv->height < 0)
|
||||
return FALSE;
|
||||
|
||||
if (width != NULL)
|
||||
*width = ceilf (priv->width * priv->scale_factor);
|
||||
|
||||
if (height != NULL)
|
||||
*height = ceilf (priv->height * priv->scale_factor);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_content_iface_init (ClutterContentInterface *iface)
|
||||
{
|
||||
iface->invalidate = clutter_canvas_invalidate;
|
||||
iface->paint_content = clutter_canvas_paint_content;
|
||||
iface->get_preferred_size = clutter_canvas_get_preferred_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_canvas_new:
|
||||
*
|
||||
* Creates a new instance of #ClutterCanvas.
|
||||
*
|
||||
* You should call clutter_canvas_set_size() to set the size of the canvas.
|
||||
*
|
||||
* You should call clutter_content_invalidate() every time you wish to
|
||||
* draw the contents of the canvas.
|
||||
*
|
||||
* Return value: (transfer full): The newly allocated instance of
|
||||
* #ClutterCanvas. Use g_object_unref() when done.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
ClutterContent *
|
||||
clutter_canvas_new (void)
|
||||
{
|
||||
return g_object_new (CLUTTER_TYPE_CANVAS, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_canvas_invalidate_internal (ClutterCanvas *canvas,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
gboolean width_changed = FALSE, height_changed = FALSE;
|
||||
gboolean res = FALSE;
|
||||
GObject *obj;
|
||||
|
||||
obj = G_OBJECT (canvas);
|
||||
|
||||
g_object_freeze_notify (obj);
|
||||
|
||||
if (canvas->priv->width != width)
|
||||
{
|
||||
canvas->priv->width = width;
|
||||
width_changed = TRUE;
|
||||
|
||||
g_object_notify_by_pspec (obj, obj_props[PROP_WIDTH]);
|
||||
}
|
||||
|
||||
if (canvas->priv->height != height)
|
||||
{
|
||||
canvas->priv->height = height;
|
||||
height_changed = TRUE;
|
||||
|
||||
g_object_notify_by_pspec (obj, obj_props[PROP_HEIGHT]);
|
||||
}
|
||||
|
||||
if (width_changed || height_changed)
|
||||
{
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (canvas));
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
g_object_thaw_notify (obj);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_canvas_set_size:
|
||||
* @canvas: a #ClutterCanvas
|
||||
* @width: the width of the canvas, in pixels
|
||||
* @height: the height of the canvas, in pixels
|
||||
*
|
||||
* Sets the size of the @canvas, and invalidates the content.
|
||||
*
|
||||
* This function will cause the @canvas to be invalidated only
|
||||
* if the size of the canvas surface has changed.
|
||||
*
|
||||
* If you want to invalidate the contents of the @canvas when setting
|
||||
* the size, you can use the return value of the function to conditionally
|
||||
* call clutter_content_invalidate():
|
||||
*
|
||||
* |[
|
||||
* if (!clutter_canvas_set_size (canvas, width, height))
|
||||
* clutter_content_invalidate (CLUTTER_CONTENT (canvas));
|
||||
* ]|
|
||||
*
|
||||
* Return value: this function returns %TRUE if the size change
|
||||
* caused a content invalidation, and %FALSE otherwise
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
gboolean
|
||||
clutter_canvas_set_size (ClutterCanvas *canvas,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_CANVAS (canvas), FALSE);
|
||||
g_return_val_if_fail (width >= -1 && height >= -1, FALSE);
|
||||
|
||||
return clutter_canvas_invalidate_internal (canvas, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_canvas_set_scale_factor:
|
||||
* @canvas: a #ClutterCanvas
|
||||
* @scale: the integer scaling factor of the canvas
|
||||
*
|
||||
* Sets the scaling factor of the @canvas, and invalidates the content.
|
||||
*
|
||||
* This function will cause the @canvas to be invalidated only
|
||||
* if the scale factor of the canvas surface has changed.
|
||||
*/
|
||||
void
|
||||
clutter_canvas_set_scale_factor (ClutterCanvas *canvas,
|
||||
float scale)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_CANVAS (canvas));
|
||||
g_return_if_fail (scale > 0.0f);
|
||||
|
||||
if (canvas->priv->scale_factor != scale)
|
||||
{
|
||||
canvas->priv->scale_factor = scale;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (canvas));
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (canvas));
|
||||
g_object_thaw_notify (G_OBJECT (canvas));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (canvas), obj_props[PROP_SCALE_FACTOR]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_canvas_get_scale_factor:
|
||||
* @canvas: a #ClutterCanvas
|
||||
*
|
||||
* Gets the scale factor of the @canvas.
|
||||
*
|
||||
* Return value: the current @canvas scale factor or -1 if invalid
|
||||
*/
|
||||
float
|
||||
clutter_canvas_get_scale_factor (ClutterCanvas *canvas)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_CANVAS (canvas), -1.0f);
|
||||
|
||||
return canvas->priv->scale_factor;
|
||||
}
|
||||
106
clutter/clutter/clutter-canvas.h
Normal file
106
clutter/clutter/clutter-canvas.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2012 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_CANVAS_H__
|
||||
#define __CLUTTER_CANVAS_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <clutter/clutter-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_CANVAS (clutter_canvas_get_type ())
|
||||
#define CLUTTER_CANVAS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CANVAS, ClutterCanvas))
|
||||
#define CLUTTER_IS_CANVAS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CANVAS))
|
||||
#define CLUTTER_CANVAS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CANVAS, ClutterCanvasClass))
|
||||
#define CLUTTER_IS_CANVAS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CANVAS))
|
||||
#define CLUTTER_CANVAS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CANVAS, ClutterCanvasClass))
|
||||
|
||||
typedef struct _ClutterCanvas ClutterCanvas;
|
||||
typedef struct _ClutterCanvasPrivate ClutterCanvasPrivate;
|
||||
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
|
||||
{
|
||||
/*< private >*/
|
||||
GObject parent_instance;
|
||||
|
||||
ClutterCanvasPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterCanvasClass:
|
||||
* @draw: class handler for the #ClutterCanvas::draw signal
|
||||
*
|
||||
* The #ClutterCanvasClass structure contains
|
||||
* private data.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
struct _ClutterCanvasClass
|
||||
{
|
||||
/*< private >*/
|
||||
GObjectClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
gboolean (* draw) (ClutterCanvas *canvas,
|
||||
cairo_t *cr,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
/*< private >*/
|
||||
gpointer _padding[16];
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_canvas_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterContent * clutter_canvas_new (void);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_canvas_set_size (ClutterCanvas *canvas,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_canvas_set_scale_factor (ClutterCanvas *canvas,
|
||||
float scale);
|
||||
CLUTTER_EXPORT
|
||||
float clutter_canvas_get_scale_factor (ClutterCanvas *canvas);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_CANVAS_H__ */
|
||||
191
clutter/clutter/clutter-child-meta.c
Normal file
191
clutter/clutter/clutter-child-meta.c
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||
* Jorn Baayen <jorn@openedhand.com>
|
||||
* Emmanuele Bassi <ebassi@openedhand.com>
|
||||
* Tomas Frydrych <tf@openedhand.com>
|
||||
* Øyvind Kolås <ok@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2008 OpenedHand
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:clutter-child-meta
|
||||
* @short_description: Wrapper for actors inside a container
|
||||
*
|
||||
* #ClutterChildMeta is a wrapper object created by #ClutterContainer
|
||||
* implementations in order to store child-specific data and properties.
|
||||
*
|
||||
* A #ClutterChildMeta wraps a #ClutterActor inside a #ClutterContainer.
|
||||
*
|
||||
* #ClutterChildMeta is available since Clutter 0.8
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter-child-meta.h"
|
||||
#include "clutter-container.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (ClutterChildMeta, clutter_child_meta, G_TYPE_OBJECT);
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_CONTAINER,
|
||||
PROP_ACTOR,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
static void
|
||||
clutter_child_meta_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterChildMeta *child_meta = CLUTTER_CHILD_META (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTAINER:
|
||||
child_meta->container = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
case PROP_ACTOR:
|
||||
child_meta->actor = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_child_meta_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterChildMeta *child_meta = CLUTTER_CHILD_META (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTAINER:
|
||||
g_value_set_object (value, child_meta->container);
|
||||
break;
|
||||
|
||||
case PROP_ACTOR:
|
||||
g_value_set_object (value, child_meta->actor);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_child_meta_class_init (ClutterChildMetaClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->set_property = clutter_child_meta_set_property;
|
||||
gobject_class->get_property = clutter_child_meta_get_property;
|
||||
|
||||
/**
|
||||
* ClutterChildMeta:container:
|
||||
*
|
||||
* The #ClutterContainer that created this #ClutterChildMeta.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
obj_props[PROP_CONTAINER] =
|
||||
g_param_spec_object ("container",
|
||||
P_("Container"),
|
||||
P_("The container that created this data"),
|
||||
CLUTTER_TYPE_CONTAINER,
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* ClutterChildMeta:actor:
|
||||
*
|
||||
* The #ClutterActor being wrapped by this #ClutterChildMeta
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
obj_props[PROP_ACTOR] =
|
||||
g_param_spec_object ("actor",
|
||||
P_("Actor"),
|
||||
P_("The actor wrapped by this data"),
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (gobject_class,
|
||||
PROP_LAST,
|
||||
obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_child_meta_init (ClutterChildMeta *self)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_child_meta_get_container:
|
||||
* @data: a #ClutterChildMeta
|
||||
*
|
||||
* Retrieves the container using @data
|
||||
*
|
||||
* Return value: (transfer none): a #ClutterContainer
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
ClutterContainer *
|
||||
clutter_child_meta_get_container (ClutterChildMeta *data)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_CHILD_META (data), NULL);
|
||||
|
||||
return data->container;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_child_meta_get_actor:
|
||||
* @data: a #ClutterChildMeta
|
||||
*
|
||||
* Retrieves the actor wrapped by @data
|
||||
*
|
||||
* Return value: (transfer none): a #ClutterActor
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_child_meta_get_actor (ClutterChildMeta *data)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_CHILD_META (data), NULL);
|
||||
|
||||
return data->actor;
|
||||
}
|
||||
122
clutter/clutter/clutter-child-meta.h
Normal file
122
clutter/clutter/clutter-child-meta.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||
* Jorn Baayen <jorn@openedhand.com>
|
||||
* Emmanuele Bassi <ebassi@openedhand.com>
|
||||
* Tomas Frydrych <tf@openedhand.com>
|
||||
* Øyvind Kolås <ok@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2008 OpenedHand
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_CHILD_META_H__
|
||||
#define __CLUTTER_CHILD_META_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <clutter/clutter-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_CHILD_META (clutter_child_meta_get_type ())
|
||||
#define CLUTTER_CHILD_META(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CHILD_META, ClutterChildMeta))
|
||||
#define CLUTTER_CHILD_META_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CHILD_META, ClutterChildMetaClass))
|
||||
#define CLUTTER_IS_CHILD_META(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CHILD_META))
|
||||
#define CLUTTER_IS_CHILD_META_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CHILD_META))
|
||||
#define CLUTTER_CHILD_META_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CHILD_META, 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
|
||||
{
|
||||
/*< private >*/
|
||||
GObject parent_instance;
|
||||
|
||||
/*< public >*/
|
||||
ClutterContainer *container;
|
||||
ClutterActor *actor;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterChildMetaClass:
|
||||
*
|
||||
* The #ClutterChildMetaClass contains only private data
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
struct _ClutterChildMetaClass
|
||||
{
|
||||
/*< private >*/
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_child_meta_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterContainer * clutter_child_meta_get_container (ClutterChildMeta *data);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_child_meta_get_actor (ClutterChildMeta *data);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_CHILD_META_H__ */
|
||||
@@ -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 [class@Action] that implements
|
||||
* #ClutterClickAction is a sub-class of #ClutterAction that implements
|
||||
* the logic for clickable actors, by using the low level events of
|
||||
* [class@Actor], such as [signal@Actor::button-press-event] and
|
||||
* [signal@Actor::button-release-event], to synthesize the high level
|
||||
* [signal@ClickAction::clicked] signal.
|
||||
* #ClutterActor, such as #ClutterActor::button-press-event and
|
||||
* #ClutterActor::button-release-event, to synthesize the high level
|
||||
* #ClutterClickAction::clicked signal.
|
||||
*
|
||||
* To use #ClutterClickAction you just need to apply it to a [class@Actor]
|
||||
* using [method@Actor.add_action] and connect to the
|
||||
* [signal@ClickAction::clicked] signal:
|
||||
* To use #ClutterClickAction you just need to apply it to a #ClutterActor
|
||||
* using clutter_actor_add_action() and connect to the
|
||||
* #ClutterClickAction::clicked signal:
|
||||
*
|
||||
* ```c
|
||||
* |[
|
||||
* ClutterAction *action = clutter_click_action_new ();
|
||||
*
|
||||
* clutter_actor_add_action (actor, action);
|
||||
*
|
||||
* g_signal_connect (action, "clicked", G_CALLBACK (on_clicked), NULL);
|
||||
* ```
|
||||
* ]|
|
||||
*
|
||||
* #ClutterClickAction also supports long press gestures: a long press is
|
||||
* activated if the pointer remains pressed within a certain threshold (as
|
||||
* defined by the [property@ClickAction:long-press-threshold] property) for a
|
||||
* defined by the #ClutterClickAction:long-press-threshold property) for a
|
||||
* minimum amount of time (as the defined by the
|
||||
* [property@ClickAction:long-press-duration] property).
|
||||
* The [signal@ClickAction::long-press] signal is emitted multiple times,
|
||||
* using different [enum@LongPressState] values; to handle long presses
|
||||
* you should connect to the [signal@ClickAction::long-press] signal and
|
||||
* #ClutterClickAction:long-press-duration property).
|
||||
* The #ClutterClickAction::long-press signal is emitted multiple times,
|
||||
* using different #ClutterLongPressState values; to handle long presses
|
||||
* you should connect to the #ClutterClickAction::long-press signal and
|
||||
* handle the different states:
|
||||
*
|
||||
* ```c
|
||||
* |[
|
||||
* static gboolean
|
||||
* on_long_press (ClutterClickAction *action,
|
||||
* ClutterActor *actor,
|
||||
@@ -64,42 +64,49 @@
|
||||
* switch (state)
|
||||
* {
|
||||
* case CLUTTER_LONG_PRESS_QUERY:
|
||||
* // return TRUE if the actor should support long press
|
||||
* // gestures, and FALSE otherwise; this state will be
|
||||
* // emitted on button presses
|
||||
* /* return TRUE if the actor should support long press
|
||||
* * gestures, and FALSE otherwise; this state will be
|
||||
* * emitted on button presses
|
||||
* */
|
||||
* return TRUE;
|
||||
*
|
||||
* case CLUTTER_LONG_PRESS_ACTIVATE:
|
||||
* // this state is emitted if the minimum duration has
|
||||
* // been reached without the gesture being cancelled.
|
||||
* // the return value is not used
|
||||
* /* this state is emitted if the minimum duration has
|
||||
* * been reached without the gesture being cancelled.
|
||||
* * the return value is not used
|
||||
* */
|
||||
* return TRUE;
|
||||
*
|
||||
* case CLUTTER_LONG_PRESS_CANCEL:
|
||||
* // this state is emitted if the long press was cancelled;
|
||||
* // for instance, the pointer went outside the actor or the
|
||||
* // allowed threshold, or the button was released before
|
||||
* // the minimum duration was reached. the return value is
|
||||
* // not used
|
||||
* /* this state is emitted if the long press was cancelled;
|
||||
* * for instance, the pointer went outside the actor or the
|
||||
* * allowed threshold, or the button was released before
|
||||
* * the minimum duration was reached. the return value is
|
||||
* * not used
|
||||
* */
|
||||
* return FALSE;
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
* ]|
|
||||
*
|
||||
* #ClutterClickAction is available since Clutter 1.4
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter/clutter-click-action.h"
|
||||
#include "clutter-click-action.h"
|
||||
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-enum-types.h"
|
||||
#include "clutter/clutter-marshal.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-enum-types.h"
|
||||
#include "clutter-marshal.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
struct _ClutterClickActionPrivate
|
||||
{
|
||||
ClutterActor *stage;
|
||||
|
||||
guint event_id;
|
||||
guint capture_id;
|
||||
guint long_press_id;
|
||||
|
||||
gint long_press_threshold;
|
||||
@@ -107,7 +114,7 @@ struct _ClutterClickActionPrivate
|
||||
gint drag_threshold;
|
||||
|
||||
guint press_button;
|
||||
ClutterInputDevice *press_device;
|
||||
gint press_device_id;
|
||||
ClutterEventSequence *press_sequence;
|
||||
ClutterModifierType modifier_state;
|
||||
gfloat press_x;
|
||||
@@ -143,12 +150,16 @@ static guint click_signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterClickAction, clutter_click_action, CLUTTER_TYPE_ACTION)
|
||||
|
||||
/* forward declaration */
|
||||
static gboolean on_captured_event (ClutterActor *stage,
|
||||
ClutterEvent *event,
|
||||
ClutterClickAction *action);
|
||||
|
||||
static inline void
|
||||
click_action_set_pressed (ClutterClickAction *action,
|
||||
gboolean is_pressed)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
ClutterClickActionPrivate *priv = action->priv;
|
||||
|
||||
is_pressed = !!is_pressed;
|
||||
|
||||
@@ -163,8 +174,7 @@ static inline void
|
||||
click_action_set_held (ClutterClickAction *action,
|
||||
gboolean is_held)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
ClutterClickActionPrivate *priv = action->priv;
|
||||
|
||||
is_held = !!is_held;
|
||||
|
||||
@@ -179,8 +189,7 @@ static gboolean
|
||||
click_action_emit_long_press (gpointer data)
|
||||
{
|
||||
ClutterClickAction *action = data;
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
ClutterClickActionPrivate *priv = action->priv;
|
||||
ClutterActor *actor;
|
||||
gboolean result;
|
||||
|
||||
@@ -193,6 +202,12 @@ click_action_emit_long_press (gpointer data)
|
||||
CLUTTER_LONG_PRESS_ACTIVATE,
|
||||
&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_held (action, FALSE);
|
||||
|
||||
@@ -202,17 +217,14 @@ click_action_emit_long_press (gpointer data)
|
||||
static inline void
|
||||
click_action_query_long_press (ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
ClutterActor *actor =
|
||||
clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
||||
ClutterContext *context = clutter_actor_get_context (actor);
|
||||
ClutterClickActionPrivate *priv = action->priv;
|
||||
ClutterActor *actor;
|
||||
gboolean result = FALSE;
|
||||
gint timeout;
|
||||
|
||||
if (priv->long_press_duration < 0)
|
||||
{
|
||||
ClutterSettings *settings = clutter_context_get_settings (context);
|
||||
ClutterSettings *settings = clutter_settings_get_default ();
|
||||
|
||||
g_object_get (settings,
|
||||
"long-press-duration", &timeout,
|
||||
@@ -221,6 +233,7 @@ click_action_query_long_press (ClutterClickAction *action)
|
||||
else
|
||||
timeout = priv->long_press_duration;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
||||
|
||||
g_signal_emit (action, click_signals[LONG_PRESS], 0,
|
||||
actor,
|
||||
@@ -229,18 +242,17 @@ click_action_query_long_press (ClutterClickAction *action)
|
||||
|
||||
if (result)
|
||||
{
|
||||
g_clear_handle_id (&priv->long_press_id, g_source_remove);
|
||||
priv->long_press_id = g_timeout_add (timeout,
|
||||
click_action_emit_long_press,
|
||||
action);
|
||||
priv->long_press_id =
|
||||
clutter_threads_add_timeout (timeout,
|
||||
click_action_emit_long_press,
|
||||
action);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
click_action_cancel_long_press (ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
ClutterClickActionPrivate *priv = action->priv;
|
||||
|
||||
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));
|
||||
|
||||
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,
|
||||
actor,
|
||||
@@ -258,74 +271,40 @@ click_action_cancel_long_press (ClutterClickAction *action)
|
||||
}
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
event_within_drag_threshold (ClutterClickAction *click_action,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (click_action);
|
||||
float motion_x, motion_y;
|
||||
float delta_x, delta_y;
|
||||
|
||||
clutter_event_get_coords (event, &motion_x, &motion_y);
|
||||
|
||||
delta_x = ABS (motion_x - priv->press_x);
|
||||
delta_y = ABS (motion_y - priv->press_y);
|
||||
|
||||
return delta_x <= priv->drag_threshold && delta_y <= priv->drag_threshold;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_click_action_handle_event (ClutterAction *action,
|
||||
const ClutterEvent *event)
|
||||
on_event (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickAction *click_action = CLUTTER_CLICK_ACTION (action);
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (click_action);
|
||||
ClutterActor *actor =
|
||||
clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
||||
ClutterContext *context = clutter_actor_get_context (actor);
|
||||
ClutterClickActionPrivate *priv = action->priv;
|
||||
gboolean has_button = TRUE;
|
||||
ClutterModifierType modifier_state;
|
||||
ClutterActor *target;
|
||||
|
||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if (priv->press_sequence != NULL &&
|
||||
clutter_event_get_event_sequence (event) != priv->press_sequence)
|
||||
{
|
||||
click_action_set_held (click_action, FALSE);
|
||||
click_action_cancel_long_press (click_action);
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
switch (clutter_event_type (event))
|
||||
{
|
||||
case CLUTTER_TOUCH_BEGIN:
|
||||
has_button = FALSE;
|
||||
|
||||
G_GNUC_FALLTHROUGH;
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
if (has_button && clutter_event_get_click_count (event) != 1)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if (priv->is_held)
|
||||
return CLUTTER_EVENT_STOP;
|
||||
|
||||
target = clutter_stage_get_device_actor (CLUTTER_STAGE (clutter_actor_get_stage (actor)),
|
||||
clutter_event_get_device (event),
|
||||
clutter_event_get_event_sequence (event));
|
||||
|
||||
if (!clutter_actor_contains (actor, target))
|
||||
if (!clutter_actor_contains (actor, clutter_event_get_source (event)))
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
priv->press_button = has_button ? clutter_event_get_button (event) : 0;
|
||||
priv->press_device = clutter_event_get_device (event);
|
||||
priv->press_device_id = clutter_event_get_device_id (event);
|
||||
priv->press_sequence = clutter_event_get_event_sequence (event);
|
||||
priv->modifier_state = clutter_event_get_state (event);
|
||||
clutter_event_get_coords (event, &priv->press_x, &priv->press_y);
|
||||
|
||||
if (priv->long_press_threshold < 0)
|
||||
{
|
||||
ClutterSettings *settings = clutter_context_get_settings (context);
|
||||
ClutterSettings *settings = clutter_settings_get_default ();
|
||||
|
||||
g_object_get (settings,
|
||||
"dnd-drag-threshold", &priv->drag_threshold,
|
||||
@@ -337,47 +316,78 @@ clutter_click_action_handle_event (ClutterAction *action,
|
||||
if (priv->stage == NULL)
|
||||
priv->stage = clutter_actor_get_stage (actor);
|
||||
|
||||
click_action_set_pressed (click_action, TRUE);
|
||||
click_action_set_held (click_action, TRUE);
|
||||
click_action_query_long_press (click_action);
|
||||
priv->capture_id = g_signal_connect_after (priv->stage, "captured-event",
|
||||
G_CALLBACK (on_captured_event),
|
||||
action);
|
||||
|
||||
click_action_set_pressed (action, TRUE);
|
||||
click_action_set_held (action, TRUE);
|
||||
click_action_query_long_press (action);
|
||||
break;
|
||||
|
||||
case CLUTTER_ENTER:
|
||||
click_action_set_pressed (click_action, priv->is_held);
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
click_action_set_pressed (action, priv->is_held);
|
||||
break;
|
||||
|
||||
case CLUTTER_LEAVE:
|
||||
click_action_set_pressed (click_action, FALSE);
|
||||
click_action_cancel_long_press (click_action);
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
click_action_set_pressed (action, priv->is_held);
|
||||
click_action_cancel_long_press (action);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_captured_event (ClutterActor *stage,
|
||||
ClutterEvent *event,
|
||||
ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickActionPrivate *priv = action->priv;
|
||||
ClutterActor *actor;
|
||||
ClutterModifierType modifier_state;
|
||||
gboolean has_button = TRUE;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
||||
|
||||
switch (clutter_event_type (event))
|
||||
{
|
||||
case CLUTTER_TOUCH_CANCEL:
|
||||
clutter_click_action_release (click_action);
|
||||
clutter_click_action_release (action);
|
||||
break;
|
||||
|
||||
case CLUTTER_TOUCH_END:
|
||||
has_button = FALSE;
|
||||
|
||||
G_GNUC_FALLTHROUGH;
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
if (!priv->is_held)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
return CLUTTER_EVENT_STOP;
|
||||
|
||||
if ((has_button && clutter_event_get_button (event) != priv->press_button) ||
|
||||
clutter_event_get_device (event) != priv->press_device ||
|
||||
(has_button && clutter_event_get_click_count (event) != 1) ||
|
||||
clutter_event_get_device_id (event) != priv->press_device_id ||
|
||||
clutter_event_get_event_sequence (event) != priv->press_sequence)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
click_action_set_held (click_action, FALSE);
|
||||
click_action_cancel_long_press (click_action);
|
||||
click_action_set_held (action, FALSE);
|
||||
click_action_cancel_long_press (action);
|
||||
|
||||
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_STAGE (clutter_actor_get_stage (actor)),
|
||||
clutter_event_get_device (event),
|
||||
clutter_event_get_event_sequence (event));
|
||||
if (priv->long_press_id != 0)
|
||||
{
|
||||
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;
|
||||
|
||||
/* exclude any button-mask so that we can compare
|
||||
@@ -396,24 +406,31 @@ clutter_click_action_handle_event (ClutterAction *action,
|
||||
if (modifier_state != priv->modifier_state)
|
||||
priv->modifier_state = 0;
|
||||
|
||||
click_action_set_pressed (click_action, FALSE);
|
||||
|
||||
if (event_within_drag_threshold (click_action, event))
|
||||
g_signal_emit (click_action, click_signals[CLICKED], 0, actor);
|
||||
click_action_set_pressed (action, FALSE);
|
||||
g_signal_emit (action, click_signals[CLICKED], 0, actor);
|
||||
break;
|
||||
|
||||
case CLUTTER_MOTION:
|
||||
case CLUTTER_TOUCH_UPDATE:
|
||||
{
|
||||
if (clutter_event_get_device (event) != priv->press_device ||
|
||||
gfloat motion_x, motion_y;
|
||||
gfloat delta_x, delta_y;
|
||||
|
||||
if (clutter_event_get_device_id (event) != priv->press_device_id ||
|
||||
clutter_event_get_event_sequence (event) != priv->press_sequence)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if (!priv->is_held)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if (!event_within_drag_threshold (click_action, event))
|
||||
clutter_click_action_release (click_action);
|
||||
clutter_event_get_coords (event, &motion_x, &motion_y);
|
||||
|
||||
delta_x = ABS (motion_x - priv->press_x);
|
||||
delta_y = ABS (motion_y - priv->press_y);
|
||||
|
||||
if (delta_x > priv->drag_threshold ||
|
||||
delta_y > priv->drag_threshold)
|
||||
click_action_cancel_long_press (action);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -421,20 +438,7 @@ clutter_click_action_handle_event (ClutterAction *action,
|
||||
break;
|
||||
}
|
||||
|
||||
return priv->is_held ? CLUTTER_EVENT_STOP : CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_click_action_sequence_cancelled (ClutterAction *action,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence)
|
||||
{
|
||||
ClutterClickAction *self = CLUTTER_CLICK_ACTION (action);
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (self);
|
||||
|
||||
if (priv->press_device == device && priv->press_sequence == sequence)
|
||||
clutter_click_action_release (self);
|
||||
return CLUTTER_EVENT_STOP;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -442,39 +446,51 @@ clutter_click_action_set_actor (ClutterActorMeta *meta,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterClickAction *action = CLUTTER_CLICK_ACTION (meta);
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
ClutterClickActionPrivate *priv = action->priv;
|
||||
|
||||
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_held (action, FALSE);
|
||||
|
||||
if (actor != NULL)
|
||||
priv->event_id = g_signal_connect (actor, "event",
|
||||
G_CALLBACK (on_event),
|
||||
action);
|
||||
|
||||
CLUTTER_ACTOR_META_CLASS (clutter_click_action_parent_class)->set_actor (meta, actor);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_click_action_set_enabled (ClutterActorMeta *meta,
|
||||
gboolean is_enabled)
|
||||
{
|
||||
ClutterClickAction *click_action = CLUTTER_CLICK_ACTION (meta);
|
||||
ClutterActorMetaClass *parent_class =
|
||||
CLUTTER_ACTOR_META_CLASS (clutter_click_action_parent_class);
|
||||
|
||||
if (!is_enabled)
|
||||
clutter_click_action_release (click_action);
|
||||
|
||||
parent_class->set_enabled (meta, is_enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_click_action_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
|
||||
ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
@@ -498,8 +514,7 @@ clutter_click_action_get_property (GObject *gobject,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
|
||||
ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
@@ -528,26 +543,38 @@ clutter_click_action_get_property (GObject *gobject,
|
||||
static void
|
||||
clutter_click_action_dispose (GObject *gobject)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
|
||||
ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv;
|
||||
|
||||
g_clear_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);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
clutter_click_action_class_init (ClutterClickActionClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
|
||||
ClutterActionClass *action_class = CLUTTER_ACTION_CLASS (klass);
|
||||
|
||||
action_class->handle_event = clutter_click_action_handle_event;
|
||||
action_class->sequence_cancelled = clutter_click_action_sequence_cancelled;
|
||||
|
||||
meta_class->set_actor = clutter_click_action_set_actor;
|
||||
meta_class->set_enabled = clutter_click_action_set_enabled;
|
||||
|
||||
gobject_class->dispose = clutter_click_action_dispose;
|
||||
gobject_class->set_property = clutter_click_action_set_property;
|
||||
@@ -557,23 +584,29 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
|
||||
* ClutterClickAction:pressed:
|
||||
*
|
||||
* Whether the clickable actor should be in "pressed" state
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
obj_props[PROP_PRESSED] =
|
||||
g_param_spec_boolean ("pressed", NULL, NULL,
|
||||
g_param_spec_boolean ("pressed",
|
||||
P_("Pressed"),
|
||||
P_("Whether the clickable should be in pressed state"),
|
||||
FALSE,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
CLUTTER_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* ClutterClickAction:held:
|
||||
*
|
||||
* Whether the clickable actor has the pointer grabbed
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
obj_props[PROP_HELD] =
|
||||
g_param_spec_boolean ("held", NULL, NULL,
|
||||
g_param_spec_boolean ("held",
|
||||
P_("Held"),
|
||||
P_("Whether the clickable has a grab"),
|
||||
FALSE,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
CLUTTER_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* ClutterClickAction:long-press-duration:
|
||||
@@ -582,14 +615,17 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
|
||||
* press gesture, in milliseconds.
|
||||
*
|
||||
* 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] =
|
||||
g_param_spec_int ("long-press-duration", NULL, NULL,
|
||||
g_param_spec_int ("long-press-duration",
|
||||
P_("Long Press Duration"),
|
||||
P_("The minimum duration of a long press to recognize the gesture"),
|
||||
-1, G_MAXINT,
|
||||
-1,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* ClutterClickAction:long-press-threshold:
|
||||
@@ -598,14 +634,17 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
|
||||
* a long press gesture is cancelled, in pixels.
|
||||
*
|
||||
* A value of -1 will make the #ClutterClickAction use the value of
|
||||
* the [property@Settings:dnd-drag-threshold] property.
|
||||
* the #ClutterSettings:dnd-drag-threshold property.
|
||||
*
|
||||
* Since: 1.8
|
||||
*/
|
||||
obj_props[PROP_LONG_PRESS_THRESHOLD] =
|
||||
g_param_spec_int ("long-press-threshold", NULL, NULL,
|
||||
g_param_spec_int ("long-press-threshold",
|
||||
P_("Long Press Threshold"),
|
||||
P_("The maximum threshold before a long press is cancelled"),
|
||||
-1, G_MAXINT,
|
||||
-1,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (gobject_class,
|
||||
PROP_LAST,
|
||||
@@ -616,16 +655,19 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
|
||||
* @action: the #ClutterClickAction that emitted the signal
|
||||
* @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
|
||||
* pointer button press and release events
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
click_signals[CLICKED] =
|
||||
g_signal_new (I_("clicked"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterClickActionClass, clicked),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_ACTOR);
|
||||
|
||||
@@ -635,7 +677,7 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
|
||||
* @actor: the #ClutterActor attached to the @action
|
||||
* @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.
|
||||
*
|
||||
* This signal can be emitted multiple times with different states.
|
||||
@@ -649,10 +691,12 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
|
||||
* %CLUTTER_LONG_PRESS_CANCEL state if the long press was cancelled.
|
||||
*
|
||||
* It is possible to forcibly cancel a long press detection using
|
||||
* [method@ClickAction.release].
|
||||
* clutter_click_action_release().
|
||||
*
|
||||
* Return value: Only the %CLUTTER_LONG_PRESS_QUERY state uses the
|
||||
* returned value of the handler; other states will ignore it
|
||||
*
|
||||
* Since: 1.8
|
||||
*/
|
||||
click_signals[LONG_PRESS] =
|
||||
g_signal_new (I_("long-press"),
|
||||
@@ -669,11 +713,9 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
|
||||
static void
|
||||
clutter_click_action_init (ClutterClickAction *self)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (self);
|
||||
|
||||
priv->long_press_threshold = -1;
|
||||
priv->long_press_duration = -1;
|
||||
self->priv = clutter_click_action_get_instance_private (self);
|
||||
self->priv->long_press_threshold = -1;
|
||||
self->priv->long_press_duration = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -682,6 +724,8 @@ clutter_click_action_init (ClutterClickAction *self)
|
||||
* Creates a new #ClutterClickAction instance
|
||||
*
|
||||
* Return value: the newly created #ClutterClickAction
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
ClutterAction *
|
||||
clutter_click_action_new (void)
|
||||
@@ -694,13 +738,15 @@ clutter_click_action_new (void)
|
||||
* @action: a #ClutterClickAction
|
||||
*
|
||||
* 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
|
||||
* initiated.
|
||||
*
|
||||
* This function is useful to break a grab, for instance after a certain
|
||||
* amount of time has passed.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
clutter_click_action_release (ClutterClickAction *action)
|
||||
@@ -709,11 +755,18 @@ clutter_click_action_release (ClutterClickAction *action)
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_CLICK_ACTION (action));
|
||||
|
||||
priv = clutter_click_action_get_instance_private (action);
|
||||
priv = action->priv;
|
||||
|
||||
if (!priv->is_held)
|
||||
return;
|
||||
|
||||
/* disconnect the capture */
|
||||
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_set_held (action, FALSE);
|
||||
click_action_set_pressed (action, FALSE);
|
||||
@@ -726,17 +779,15 @@ clutter_click_action_release (ClutterClickAction *action)
|
||||
* Retrieves the button that was pressed.
|
||||
*
|
||||
* Return value: the button value
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
guint
|
||||
clutter_click_action_get_button (ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickActionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0);
|
||||
|
||||
priv = clutter_click_action_get_instance_private (action);
|
||||
|
||||
return priv->press_button;
|
||||
return action->priv->press_button;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -746,17 +797,15 @@ clutter_click_action_get_button (ClutterClickAction *action)
|
||||
* Retrieves the modifier state of the click action.
|
||||
*
|
||||
* Return value: the modifier state parameter, or 0
|
||||
*
|
||||
* Since: 1.6
|
||||
*/
|
||||
ClutterModifierType
|
||||
clutter_click_action_get_state (ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickActionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0);
|
||||
|
||||
priv = clutter_click_action_get_instance_private (action);
|
||||
|
||||
return priv->modifier_state;
|
||||
return action->priv->modifier_state;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -766,21 +815,19 @@ clutter_click_action_get_state (ClutterClickAction *action)
|
||||
* @press_y: (out): return location for the Y coordinate, or %NULL
|
||||
*
|
||||
* Retrieves the screen coordinates of the button press.
|
||||
*
|
||||
* Since: 1.8
|
||||
*/
|
||||
void
|
||||
clutter_click_action_get_coords (ClutterClickAction *action,
|
||||
gfloat *press_x,
|
||||
gfloat *press_y)
|
||||
{
|
||||
ClutterClickActionPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTION (action));
|
||||
|
||||
priv = clutter_click_action_get_instance_private (action);
|
||||
|
||||
if (press_x != NULL)
|
||||
*press_x = priv->press_x;
|
||||
*press_x = action->priv->press_x;
|
||||
|
||||
if (press_y != NULL)
|
||||
*press_y = priv->press_y;
|
||||
*press_y = action->priv->press_y;
|
||||
}
|
||||
|
||||
@@ -25,24 +25,44 @@
|
||||
* Colin Walters <walters@verbum.org>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_CLICK_ACTION_H__
|
||||
#define __CLUTTER_CLICK_ACTION_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-action.h"
|
||||
#include "clutter/clutter-event.h"
|
||||
#include <clutter/clutter-action.h>
|
||||
#include <clutter/clutter-event.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_CLICK_ACTION (clutter_click_action_get_type ())
|
||||
#define CLUTTER_TYPE_CLICK_ACTION (clutter_click_action_get_type ())
|
||||
#define CLUTTER_CLICK_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CLICK_ACTION, ClutterClickAction))
|
||||
#define CLUTTER_IS_CLICK_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CLICK_ACTION))
|
||||
#define CLUTTER_CLICK_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CLICK_ACTION, ClutterClickActionClass))
|
||||
#define CLUTTER_IS_CLICK_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CLICK_ACTION))
|
||||
#define CLUTTER_CLICK_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CLICK_ACTION, ClutterClickActionClass))
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterClickAction, clutter_click_action,
|
||||
CLUTTER, CLICK_ACTION, ClutterAction);
|
||||
typedef struct _ClutterClickAction ClutterClickAction;
|
||||
typedef struct _ClutterClickActionPrivate ClutterClickActionPrivate;
|
||||
typedef struct _ClutterClickActionClass ClutterClickActionClass;
|
||||
|
||||
typedef struct _ClutterClickActionPrivate ClutterClickActionPrivate;
|
||||
/**
|
||||
* ClutterClickAction:
|
||||
*
|
||||
* The #ClutterClickAction structure contains
|
||||
* only private data and should be accessed using the provided API
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _ClutterClickAction
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterAction parent_instance;
|
||||
|
||||
ClutterClickActionPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterClickActionClass:
|
||||
@@ -51,6 +71,8 @@ typedef struct _ClutterClickActionPrivate ClutterClickActionPrivate;
|
||||
*
|
||||
* The #ClutterClickActionClass structure
|
||||
* contains only private data
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _ClutterClickActionClass
|
||||
{
|
||||
@@ -64,8 +86,20 @@ struct _ClutterClickActionClass
|
||||
gboolean (* long_press) (ClutterClickAction *action,
|
||||
ClutterActor *actor,
|
||||
ClutterLongPressState state);
|
||||
|
||||
/*< private >*/
|
||||
void (* _clutter_click_action1) (void);
|
||||
void (* _clutter_click_action2) (void);
|
||||
void (* _clutter_click_action3) (void);
|
||||
void (* _clutter_click_action4) (void);
|
||||
void (* _clutter_click_action5) (void);
|
||||
void (* _clutter_click_action6) (void);
|
||||
void (* _clutter_click_action7) (void);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_click_action_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterAction * clutter_click_action_new (void);
|
||||
|
||||
@@ -82,3 +116,5 @@ CLUTTER_EXPORT
|
||||
void clutter_click_action_release (ClutterClickAction *action);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_CLICK_ACTION_H__ */
|
||||
|
||||
@@ -22,37 +22,38 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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 [class@Clutter.Actor] which draws with the paint
|
||||
* #ClutterClone is a #ClutterActor which draws with the paint
|
||||
* function of another actor, scaled to fit its own allocation.
|
||||
*
|
||||
* #ClutterClone can be used to efficiently clone any other actor.
|
||||
*
|
||||
* #ClutterClone does not require the presence of support for FBOs
|
||||
* in the underlying GL or GLES implementation.
|
||||
* Unlike clutter_texture_new_from_actor(), #ClutterClone does not require
|
||||
* the presence of support for FBOs in the underlying GL or GLES
|
||||
* implementation.
|
||||
*
|
||||
* #ClutterClone is available since Clutter 1.0
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter/clutter-actor-private.h"
|
||||
#include "clutter/clutter-clone.h"
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-main.h"
|
||||
#include "clutter/clutter-paint-volume-private.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||
#include "clutter-actor-private.h"
|
||||
#include "clutter-clone.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-paint-volume-private.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
|
||||
typedef struct _ClutterClonePrivate
|
||||
struct _ClutterClonePrivate
|
||||
{
|
||||
ClutterActor *clone_source;
|
||||
float x_scale, y_scale;
|
||||
|
||||
gulong source_destroy_id;
|
||||
} ClutterClonePrivate;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterClone, clutter_clone, CLUTTER_TYPE_ACTOR)
|
||||
|
||||
@@ -75,8 +76,7 @@ clutter_clone_get_preferred_width (ClutterActor *self,
|
||||
gfloat *min_width_p,
|
||||
gfloat *natural_width_p)
|
||||
{
|
||||
ClutterClonePrivate *priv =
|
||||
clutter_clone_get_instance_private (CLUTTER_CLONE (self));
|
||||
ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
|
||||
ClutterActor *clone_source = priv->clone_source;
|
||||
|
||||
if (clone_source == NULL)
|
||||
@@ -100,8 +100,7 @@ clutter_clone_get_preferred_height (ClutterActor *self,
|
||||
gfloat *min_height_p,
|
||||
gfloat *natural_height_p)
|
||||
{
|
||||
ClutterClonePrivate *priv =
|
||||
clutter_clone_get_instance_private (CLUTTER_CLONE (self));
|
||||
ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
|
||||
ClutterActor *clone_source = priv->clone_source;
|
||||
|
||||
if (clone_source == NULL)
|
||||
@@ -120,11 +119,43 @@ clutter_clone_get_preferred_height (ClutterActor *self,
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_clone_paint (ClutterActor *actor,
|
||||
ClutterPaintContext *paint_context)
|
||||
clutter_clone_apply_transform (ClutterActor *self, CoglMatrix *matrix)
|
||||
{
|
||||
ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
|
||||
ClutterActorBox box, source_box;
|
||||
gfloat x_scale, y_scale;
|
||||
|
||||
/* First chain up and apply all the standard ClutterActor
|
||||
* transformations... */
|
||||
CLUTTER_ACTOR_CLASS (clutter_clone_parent_class)->apply_transform (self,
|
||||
matrix);
|
||||
|
||||
/* if we don't have a source, nothing else to do */
|
||||
if (priv->clone_source == NULL)
|
||||
return;
|
||||
|
||||
/* get our allocated size */
|
||||
clutter_actor_get_allocation_box (self, &box);
|
||||
|
||||
/* and get the allocated size of the source */
|
||||
clutter_actor_get_allocation_box (priv->clone_source, &source_box);
|
||||
|
||||
/* We need to scale what the clone-source actor paints to fill our own
|
||||
* allocation...
|
||||
*/
|
||||
x_scale = clutter_actor_box_get_width (&box)
|
||||
/ clutter_actor_box_get_width (&source_box);
|
||||
y_scale = clutter_actor_box_get_height (&box)
|
||||
/ clutter_actor_box_get_height (&source_box);
|
||||
|
||||
cogl_matrix_scale (matrix, x_scale, y_scale, x_scale);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_clone_paint (ClutterActor *actor)
|
||||
{
|
||||
ClutterClone *self = CLUTTER_CLONE (actor);
|
||||
ClutterClonePrivate *priv = clutter_clone_get_instance_private (self);
|
||||
ClutterClonePrivate *priv = self->priv;
|
||||
gboolean was_unmapped = FALSE;
|
||||
|
||||
if (priv->clone_source == NULL)
|
||||
@@ -143,7 +174,7 @@ clutter_clone_paint (ClutterActor *actor,
|
||||
*/
|
||||
_clutter_actor_set_in_clone_paint (priv->clone_source, TRUE);
|
||||
clutter_actor_set_opacity_override (priv->clone_source,
|
||||
clutter_actor_get_paint_opacity (actor));
|
||||
clutter_actor_get_paint_opacity (actor));
|
||||
_clutter_actor_set_enable_model_view_transform (priv->clone_source, FALSE);
|
||||
|
||||
if (!clutter_actor_is_mapped (priv->clone_source))
|
||||
@@ -157,22 +188,9 @@ clutter_clone_paint (ClutterActor *actor,
|
||||
*/
|
||||
if (clutter_actor_is_realized (priv->clone_source))
|
||||
{
|
||||
CoglFramebuffer *fb = NULL;
|
||||
|
||||
if (priv->x_scale != 1.0 || priv->y_scale != 1.0)
|
||||
{
|
||||
fb = clutter_paint_context_get_framebuffer (paint_context);
|
||||
|
||||
cogl_framebuffer_push_matrix (fb);
|
||||
cogl_framebuffer_scale (fb, priv->x_scale, priv->y_scale, 1.0f);
|
||||
}
|
||||
|
||||
_clutter_actor_push_clone_paint ();
|
||||
clutter_actor_paint (priv->clone_source, paint_context);
|
||||
clutter_actor_paint (priv->clone_source);
|
||||
_clutter_actor_pop_clone_paint ();
|
||||
|
||||
if (fb != NULL)
|
||||
cogl_framebuffer_pop_matrix (fb);
|
||||
}
|
||||
|
||||
if (was_unmapped)
|
||||
@@ -187,21 +205,20 @@ static gboolean
|
||||
clutter_clone_get_paint_volume (ClutterActor *actor,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
ClutterClonePrivate *priv =
|
||||
clutter_clone_get_instance_private (CLUTTER_CLONE (actor));
|
||||
ClutterClonePrivate *priv = CLUTTER_CLONE (actor)->priv;
|
||||
const ClutterPaintVolume *source_volume;
|
||||
|
||||
/* if the source is not set the paint volume is defined to be empty */
|
||||
if (priv->clone_source == NULL)
|
||||
return TRUE;
|
||||
|
||||
/* query the volume of the source actor and simply masquerade it as
|
||||
/* query the volume of the source actor and simply masquarade it as
|
||||
* the clones volume... */
|
||||
source_volume = clutter_actor_get_paint_volume (priv->clone_source);
|
||||
if (source_volume == NULL)
|
||||
return FALSE;
|
||||
|
||||
clutter_paint_volume_init_from_paint_volume (volume, source_volume);
|
||||
_clutter_paint_volume_set_from_volume (volume, source_volume);
|
||||
_clutter_paint_volume_set_reference_actor (volume, actor);
|
||||
|
||||
return TRUE;
|
||||
@@ -210,8 +227,7 @@ clutter_clone_get_paint_volume (ClutterActor *actor,
|
||||
static gboolean
|
||||
clutter_clone_has_overlaps (ClutterActor *actor)
|
||||
{
|
||||
ClutterClonePrivate *priv =
|
||||
clutter_clone_get_instance_private (CLUTTER_CLONE (actor));
|
||||
ClutterClonePrivate *priv = CLUTTER_CLONE (actor)->priv;
|
||||
|
||||
/* The clone has overlaps iff the source has overlaps */
|
||||
|
||||
@@ -223,52 +239,19 @@ clutter_clone_has_overlaps (ClutterActor *actor)
|
||||
|
||||
static void
|
||||
clutter_clone_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box)
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags)
|
||||
{
|
||||
ClutterClonePrivate *priv =
|
||||
clutter_clone_get_instance_private (CLUTTER_CLONE (self));
|
||||
ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
|
||||
ClutterActorClass *parent_class;
|
||||
ClutterActorBox source_box;
|
||||
float x_scale, y_scale;
|
||||
|
||||
/* chain up */
|
||||
parent_class = CLUTTER_ACTOR_CLASS (clutter_clone_parent_class);
|
||||
parent_class->allocate (self, box);
|
||||
parent_class->allocate (self, box, flags);
|
||||
|
||||
if (priv->clone_source == NULL)
|
||||
return;
|
||||
|
||||
/* ClutterActor delays allocating until the actor is shown; however
|
||||
* we cannot paint it correctly in that case, so force an allocation.
|
||||
*/
|
||||
if (clutter_actor_get_parent (priv->clone_source) != NULL &&
|
||||
!clutter_actor_has_allocation (priv->clone_source))
|
||||
{
|
||||
float x = 0.f;
|
||||
float y = 0.f;
|
||||
|
||||
clutter_actor_get_fixed_position (priv->clone_source, &x, &y);
|
||||
clutter_actor_allocate_preferred_size (priv->clone_source, x, y);
|
||||
}
|
||||
|
||||
clutter_actor_get_allocation_box (priv->clone_source, &source_box);
|
||||
|
||||
/* We need to scale what the clone-source actor paints to fill our own
|
||||
* allocation...
|
||||
*/
|
||||
x_scale = clutter_actor_box_get_width (box)
|
||||
/ clutter_actor_box_get_width (&source_box);
|
||||
y_scale = clutter_actor_box_get_height (box)
|
||||
/ clutter_actor_box_get_height (&source_box);
|
||||
|
||||
if (!G_APPROX_VALUE (priv->x_scale, x_scale, FLT_EPSILON) ||
|
||||
!G_APPROX_VALUE (priv->y_scale, y_scale, FLT_EPSILON))
|
||||
{
|
||||
priv->x_scale = x_scale;
|
||||
priv->y_scale = y_scale;
|
||||
clutter_actor_queue_redraw (self);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* XXX - this is wrong: ClutterClone cannot clone unparented
|
||||
* actors, as it will break all invariants
|
||||
@@ -282,7 +265,7 @@ clutter_clone_allocate (ClutterActor *self,
|
||||
* paint cycle, we can safely give it as much size as it requires
|
||||
*/
|
||||
if (clutter_actor_get_parent (priv->clone_source) == NULL)
|
||||
clutter_actor_allocate_preferred_size (priv->clone_source);
|
||||
clutter_actor_allocate_preferred_size (priv->clone_source, flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -312,8 +295,7 @@ clutter_clone_get_property (GObject *gobject,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterClonePrivate *priv =
|
||||
clutter_clone_get_instance_private (CLUTTER_CLONE (gobject));
|
||||
ClutterClonePrivate *priv = CLUTTER_CLONE (gobject)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
@@ -341,6 +323,7 @@ clutter_clone_class_init (ClutterCloneClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
actor_class->apply_transform = clutter_clone_apply_transform;
|
||||
actor_class->paint = clutter_clone_paint;
|
||||
actor_class->get_paint_volume = clutter_clone_get_paint_volume;
|
||||
actor_class->get_preferred_width = clutter_clone_get_preferred_width;
|
||||
@@ -356,13 +339,16 @@ clutter_clone_class_init (ClutterCloneClass *klass)
|
||||
* ClutterClone:source:
|
||||
*
|
||||
* This property specifies the source actor being cloned.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
obj_props[PROP_SOURCE] =
|
||||
g_param_spec_object ("source", NULL, NULL,
|
||||
g_param_spec_object ("source",
|
||||
P_("Source"),
|
||||
P_("Specifies the actor to be cloned"),
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
|
||||
}
|
||||
@@ -370,10 +356,7 @@ clutter_clone_class_init (ClutterCloneClass *klass)
|
||||
static void
|
||||
clutter_clone_init (ClutterClone *self)
|
||||
{
|
||||
ClutterClonePrivate *priv = clutter_clone_get_instance_private (self);
|
||||
|
||||
priv->x_scale = 1.f;
|
||||
priv->y_scale = 1.f;
|
||||
self->priv = clutter_clone_get_instance_private (self);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -383,14 +366,13 @@ clutter_clone_init (ClutterClone *self)
|
||||
* Creates a new #ClutterActor which clones @source/
|
||||
*
|
||||
* Return value: the newly created #ClutterClone
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_clone_new (ClutterActor *source)
|
||||
{
|
||||
return g_object_new (CLUTTER_TYPE_CLONE,
|
||||
"source", source,
|
||||
"accessible-role", ATK_ROLE_IMAGE,
|
||||
NULL);
|
||||
return g_object_new (CLUTTER_TYPE_CLONE, "source", source, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -404,14 +386,15 @@ static void
|
||||
clutter_clone_set_source_internal (ClutterClone *self,
|
||||
ClutterActor *source)
|
||||
{
|
||||
ClutterClonePrivate *priv = clutter_clone_get_instance_private (self);
|
||||
ClutterClonePrivate *priv = self->priv;
|
||||
|
||||
if (priv->clone_source == source)
|
||||
return;
|
||||
|
||||
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));
|
||||
g_object_unref (priv->clone_source);
|
||||
priv->clone_source = NULL;
|
||||
@@ -436,6 +419,8 @@ clutter_clone_set_source_internal (ClutterClone *self,
|
||||
* @source: (allow-none): a #ClutterActor, or %NULL
|
||||
*
|
||||
* Sets @source as the source actor to be cloned by @self.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_clone_set_source (ClutterClone *self,
|
||||
@@ -455,14 +440,13 @@ clutter_clone_set_source (ClutterClone *self,
|
||||
* Retrieves the source #ClutterActor being cloned by @self.
|
||||
*
|
||||
* Return value: (transfer none): the actor source for the clone
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_clone_get_source (ClutterClone *self)
|
||||
{
|
||||
ClutterClonePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_CLONE (self), NULL);
|
||||
|
||||
priv = clutter_clone_get_instance_private (self);
|
||||
return priv->clone_source;
|
||||
return self->priv->clone_source;
|
||||
}
|
||||
|
||||
@@ -21,34 +21,65 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CLUTTER_CLONE_H__
|
||||
#define __CLUTTER_CLONE_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-actor.h"
|
||||
#include <clutter/clutter-actor.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_CLONE (clutter_clone_get_type ())
|
||||
#define CLUTTER_TYPE_CLONE (clutter_clone_get_type())
|
||||
#define CLUTTER_CLONE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CLONE, ClutterClone))
|
||||
#define CLUTTER_CLONE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CLONE, ClutterCloneClass))
|
||||
#define CLUTTER_IS_CLONE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CLONE))
|
||||
#define CLUTTER_IS_CLONE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CLONE))
|
||||
#define CLUTTER_CLONE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CLONE, ClutterCloneClass))
|
||||
|
||||
typedef struct _ClutterClone ClutterClone;
|
||||
typedef struct _ClutterCloneClass ClutterCloneClass;
|
||||
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
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterActor parent_instance;
|
||||
|
||||
ClutterClonePrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterCloneClass:
|
||||
*
|
||||
* The #ClutterCloneClass structure contains only private data
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
struct _ClutterCloneClass
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
void (*_clutter_actor_clone1) (void);
|
||||
void (*_clutter_actor_clone2) (void);
|
||||
void (*_clutter_actor_clone3) (void);
|
||||
void (*_clutter_actor_clone4) (void);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterClone,
|
||||
clutter_clone,
|
||||
CLUTTER, CLONE,
|
||||
ClutterActor)
|
||||
GType clutter_clone_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_clone_new (ClutterActor *source);
|
||||
@@ -59,3 +90,5 @@ CLUTTER_EXPORT
|
||||
ClutterActor * clutter_clone_get_source (ClutterClone *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_CLONE_H__ */
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2024 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "clutter/clutter-color-manager.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
|
||||
unsigned int clutter_color_manager_get_next_id (ClutterColorManager *color_manager);
|
||||
|
||||
CoglSnippet * clutter_color_manager_lookup_snippet (ClutterColorManager *color_manager,
|
||||
const ClutterColorTransformKey *key);
|
||||
|
||||
void clutter_color_manager_add_snippet (ClutterColorManager *color_manager,
|
||||
const ClutterColorTransformKey *key,
|
||||
CoglSnippet *snippet);
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2024 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-color-manager-private.h"
|
||||
|
||||
#include "clutter/clutter-color-state-params.h"
|
||||
#include "clutter/clutter-color-state-private.h"
|
||||
#include "clutter/clutter-context.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_CONTEXT,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[N_PROPS];
|
||||
|
||||
struct _ClutterColorManager
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
ClutterContext *context;
|
||||
|
||||
GHashTable *snippet_cache;
|
||||
unsigned int id_counter;
|
||||
ClutterColorState *default_color_state;
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE (ClutterColorManager, clutter_color_manager, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
clutter_color_manager_finalize (GObject *object)
|
||||
{
|
||||
ClutterColorManager *color_manager = CLUTTER_COLOR_MANAGER (object);
|
||||
|
||||
g_clear_object (&color_manager->default_color_state);
|
||||
|
||||
g_clear_pointer (&color_manager->snippet_cache, g_hash_table_unref);
|
||||
|
||||
G_OBJECT_CLASS (clutter_color_manager_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_manager_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterColorManager *color_manager = CLUTTER_COLOR_MANAGER (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTEXT:
|
||||
color_manager->context = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_manager_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterColorManager *color_manager = CLUTTER_COLOR_MANAGER (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTEXT:
|
||||
g_value_set_object (value, color_manager->context);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_manager_class_init (ClutterColorManagerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = clutter_color_manager_finalize;
|
||||
object_class->set_property = clutter_color_manager_set_property;
|
||||
object_class->get_property = clutter_color_manager_get_property;
|
||||
|
||||
/**
|
||||
* ClutterColorManager:context:
|
||||
*
|
||||
* The associated ClutterContext.
|
||||
*/
|
||||
obj_props[PROP_CONTEXT] =
|
||||
g_param_spec_object ("context", NULL, NULL,
|
||||
CLUTTER_TYPE_CONTEXT,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_manager_init (ClutterColorManager *color_manager)
|
||||
{
|
||||
color_manager->snippet_cache =
|
||||
g_hash_table_new_full (clutter_color_transform_key_hash,
|
||||
clutter_color_transform_key_equal,
|
||||
g_free,
|
||||
g_object_unref);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
clutter_color_manager_get_next_id (ClutterColorManager *color_manager)
|
||||
{
|
||||
return ++color_manager->id_counter;
|
||||
}
|
||||
|
||||
ClutterColorState *
|
||||
clutter_color_manager_get_default_color_state (ClutterColorManager *color_manager)
|
||||
{
|
||||
if (!color_manager->default_color_state)
|
||||
{
|
||||
color_manager->default_color_state =
|
||||
clutter_color_state_params_new (color_manager->context,
|
||||
CLUTTER_COLORSPACE_SRGB,
|
||||
CLUTTER_TRANSFER_FUNCTION_SRGB);
|
||||
}
|
||||
|
||||
return color_manager->default_color_state;
|
||||
}
|
||||
|
||||
CoglSnippet *
|
||||
clutter_color_manager_lookup_snippet (ClutterColorManager *color_manager,
|
||||
const ClutterColorTransformKey *key)
|
||||
{
|
||||
return g_hash_table_lookup (color_manager->snippet_cache, key);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_color_manager_add_snippet (ClutterColorManager *color_manager,
|
||||
const ClutterColorTransformKey *key,
|
||||
CoglSnippet *snippet)
|
||||
{
|
||||
g_hash_table_insert (color_manager->snippet_cache,
|
||||
g_memdup2 (key, sizeof (*key)),
|
||||
g_object_ref (snippet));
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-color-state.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_COLORSPACE_SRGB,
|
||||
CLUTTER_COLORSPACE_BT2020,
|
||||
CLUTTER_COLORSPACE_NTSC,
|
||||
} ClutterColorspace;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_TRANSFER_FUNCTION_SRGB,
|
||||
CLUTTER_TRANSFER_FUNCTION_PQ,
|
||||
CLUTTER_TRANSFER_FUNCTION_BT709,
|
||||
CLUTTER_TRANSFER_FUNCTION_LINEAR,
|
||||
} ClutterTransferFunction;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_COLORIMETRY_TYPE_COLORSPACE,
|
||||
CLUTTER_COLORIMETRY_TYPE_PRIMARIES,
|
||||
} ClutterColorimetryType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_EOTF_TYPE_NAMED,
|
||||
CLUTTER_EOTF_TYPE_GAMMA,
|
||||
} ClutterEOTFType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_LUMINANCE_TYPE_DERIVED,
|
||||
CLUTTER_LUMINANCE_TYPE_EXPLICIT,
|
||||
} ClutterLuminanceType;
|
||||
|
||||
typedef struct _ClutterPrimaries
|
||||
{
|
||||
float r_x, r_y;
|
||||
float g_x, g_y;
|
||||
float b_x, b_y;
|
||||
float w_x, w_y;
|
||||
} ClutterPrimaries;
|
||||
|
||||
typedef struct _ClutterColorimetry
|
||||
{
|
||||
ClutterColorimetryType type : 1;
|
||||
union
|
||||
{
|
||||
ClutterColorspace colorspace;
|
||||
ClutterPrimaries *primaries;
|
||||
};
|
||||
} ClutterColorimetry;
|
||||
|
||||
typedef struct _ClutterEOTF
|
||||
{
|
||||
ClutterEOTFType type : 1;
|
||||
union
|
||||
{
|
||||
ClutterTransferFunction tf_name;
|
||||
float gamma_exp;
|
||||
};
|
||||
} ClutterEOTF;
|
||||
|
||||
typedef struct _ClutterLuminance
|
||||
{
|
||||
ClutterLuminanceType type : 1;
|
||||
float min;
|
||||
float max;
|
||||
float ref;
|
||||
} ClutterLuminance;
|
||||
|
||||
#define CLUTTER_TYPE_COLOR_STATE_PARAMS (clutter_color_state_params_get_type ())
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_FINAL_TYPE (ClutterColorStateParams, clutter_color_state_params,
|
||||
CLUTTER, COLOR_STATE_PARAMS,
|
||||
ClutterColorState)
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterColorState * clutter_color_state_params_new (ClutterContext *context,
|
||||
ClutterColorspace colorspace,
|
||||
ClutterTransferFunction transfer_function);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterColorState * clutter_color_state_params_new_full (ClutterContext *context,
|
||||
ClutterColorspace colorspace,
|
||||
ClutterTransferFunction transfer_function,
|
||||
ClutterPrimaries *primaries,
|
||||
float gamma_exp,
|
||||
float min_lum,
|
||||
float max_lum,
|
||||
float ref_lum);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterColorState * clutter_color_state_params_new_from_primitives (ClutterContext *context,
|
||||
ClutterColorimetry colorimetry,
|
||||
ClutterEOTF eotf,
|
||||
ClutterLuminance luminance);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
const ClutterColorimetry * clutter_color_state_params_get_colorimetry (ClutterColorStateParams *color_state_params);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
const ClutterEOTF * clutter_color_state_params_get_eotf (ClutterColorStateParams *color_state_params);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
const ClutterLuminance * clutter_color_state_params_get_luminance (ClutterColorStateParams *color_state_params);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
const ClutterLuminance * clutter_eotf_get_default_luminance (ClutterEOTF eotf);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
const ClutterPrimaries * clutter_colorspace_to_primaries (ClutterColorspace colorspace);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_primaries_ensure_normalized_range (ClutterPrimaries *primaries);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2024 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "clutter/clutter-color-state.h"
|
||||
|
||||
typedef struct _ClutterColorTransformKey
|
||||
{
|
||||
/* 3 bits to define TransferFunction enums
|
||||
* + 1 bit to define Gamma TF */
|
||||
guint source_eotf_bits : 4;
|
||||
guint target_eotf_bits : 4;
|
||||
/* When there is a luminance mapping snippet */
|
||||
guint luminance_bit : 1;
|
||||
/* When there is a color trans snippet */
|
||||
guint color_trans_bit : 1;
|
||||
} ClutterColorTransformKey;
|
||||
|
||||
void clutter_color_transform_key_init (ClutterColorTransformKey *key,
|
||||
ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state);
|
||||
|
||||
guint clutter_color_transform_key_hash (gconstpointer data);
|
||||
|
||||
gboolean clutter_color_transform_key_equal (gconstpointer data1,
|
||||
gconstpointer data2);
|
||||
@@ -1,383 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2022 Intel Corporation.
|
||||
* Copyright (C) 2023-2024 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Naveen Kumar <naveen1.kumar@intel.com>
|
||||
* Jonas Ådahl <jadahl@redhat.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClutterColorState:
|
||||
*
|
||||
* Color state of each ClutterActor
|
||||
*
|
||||
* The #ClutterColorState class contains the colorspace of each color
|
||||
* states (e.g. sRGB colorspace).
|
||||
*
|
||||
* Each [class@Actor] would own such an object.
|
||||
*
|
||||
* A single #ClutterColorState object can be shared by multiple [class@Actor]
|
||||
* or maybe a separate color state for each [class@Actor] (depending on whether
|
||||
* #ClutterColorState would be statefull or stateless).
|
||||
*
|
||||
* #ClutterColorState, if not set during construction, it will default to sRGB
|
||||
* color state
|
||||
*
|
||||
* The #ClutterColorState would have API to get the colorspace, whether the
|
||||
* actor content is in pq or not, and things like that
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clutter/clutter-color-state-private.h"
|
||||
|
||||
#include "clutter/clutter-color-manager-private.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_CONTEXT,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[N_PROPS];
|
||||
|
||||
typedef struct _ClutterColorStatePrivate
|
||||
{
|
||||
ClutterContext *context;
|
||||
|
||||
unsigned int id;
|
||||
} ClutterColorStatePrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterColorState,
|
||||
clutter_color_state,
|
||||
G_TYPE_OBJECT)
|
||||
|
||||
guint
|
||||
clutter_color_transform_key_hash (gconstpointer data)
|
||||
{
|
||||
const ClutterColorTransformKey *key = data;
|
||||
|
||||
return key->source_eotf_bits << 0 &
|
||||
key->target_eotf_bits << 4 &
|
||||
key->luminance_bit << 8 &
|
||||
key->color_trans_bit << 9;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_color_transform_key_equal (gconstpointer data1,
|
||||
gconstpointer data2)
|
||||
{
|
||||
const ClutterColorTransformKey *key1 = data1;
|
||||
const ClutterColorTransformKey *key2 = data2;
|
||||
|
||||
return (key1->source_eotf_bits == key2->source_eotf_bits &&
|
||||
key1->target_eotf_bits == key2->target_eotf_bits &&
|
||||
key1->luminance_bit == key2->luminance_bit &&
|
||||
key1->color_trans_bit == key2->color_trans_bit);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_color_transform_key_init (ClutterColorTransformKey *key,
|
||||
ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state)
|
||||
{
|
||||
ClutterColorStateClass *color_state_class =
|
||||
CLUTTER_COLOR_STATE_GET_CLASS (color_state);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_COLOR_STATE (color_state));
|
||||
g_return_if_fail (CLUTTER_IS_COLOR_STATE (target_color_state));
|
||||
|
||||
color_state_class->init_color_transform_key (color_state,
|
||||
target_color_state,
|
||||
key);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
clutter_color_state_get_id (ClutterColorState *color_state)
|
||||
{
|
||||
ClutterColorStatePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_COLOR_STATE (color_state), 0);
|
||||
|
||||
priv = clutter_color_state_get_instance_private (color_state);
|
||||
|
||||
return priv->id;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_state_constructed (GObject *object)
|
||||
{
|
||||
ClutterColorState *color_state = CLUTTER_COLOR_STATE (object);
|
||||
ClutterColorStatePrivate *priv =
|
||||
clutter_color_state_get_instance_private (color_state);
|
||||
ClutterColorManager *color_manager;
|
||||
|
||||
g_warn_if_fail (priv->context);
|
||||
|
||||
color_manager = clutter_context_get_color_manager (priv->context);
|
||||
|
||||
priv->id = clutter_color_manager_get_next_id (color_manager);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_state_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterColorState *color_state = CLUTTER_COLOR_STATE (object);
|
||||
ClutterColorStatePrivate *priv;
|
||||
|
||||
priv = clutter_color_state_get_instance_private (color_state);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTEXT:
|
||||
priv->context = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_state_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterColorState *color_state = CLUTTER_COLOR_STATE (object);
|
||||
ClutterColorStatePrivate *priv =
|
||||
clutter_color_state_get_instance_private (color_state);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTEXT:
|
||||
g_value_set_object (value, priv->context);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_state_class_init (ClutterColorStateClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = clutter_color_state_constructed;
|
||||
object_class->set_property = clutter_color_state_set_property;
|
||||
object_class->get_property = clutter_color_state_get_property;
|
||||
|
||||
/**
|
||||
* ClutterColorState:context:
|
||||
*
|
||||
* The associated ClutterContext.
|
||||
*/
|
||||
obj_props[PROP_CONTEXT] = g_param_spec_object ("context", NULL, NULL,
|
||||
CLUTTER_TYPE_CONTEXT,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_color_state_init (ClutterColorState *color_state)
|
||||
{
|
||||
}
|
||||
|
||||
static CoglSnippet *
|
||||
clutter_color_state_create_transform_snippet (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state)
|
||||
{
|
||||
ClutterColorStateClass *color_state_class =
|
||||
CLUTTER_COLOR_STATE_GET_CLASS (color_state);
|
||||
|
||||
return color_state_class->create_transform_snippet (color_state,
|
||||
target_color_state);
|
||||
}
|
||||
|
||||
static CoglSnippet *
|
||||
clutter_color_state_get_transform_snippet (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state)
|
||||
{
|
||||
ClutterColorStatePrivate *priv;
|
||||
ClutterColorManager *color_manager;
|
||||
ClutterColorTransformKey transform_key;
|
||||
CoglSnippet *snippet;
|
||||
|
||||
priv = clutter_color_state_get_instance_private (color_state);
|
||||
color_manager = clutter_context_get_color_manager (priv->context);
|
||||
|
||||
clutter_color_transform_key_init (&transform_key,
|
||||
color_state,
|
||||
target_color_state);
|
||||
snippet = clutter_color_manager_lookup_snippet (color_manager,
|
||||
&transform_key);
|
||||
if (snippet)
|
||||
return g_object_ref (snippet);
|
||||
|
||||
snippet = clutter_color_state_create_transform_snippet (color_state,
|
||||
target_color_state);
|
||||
|
||||
clutter_color_manager_add_snippet (color_manager,
|
||||
&transform_key,
|
||||
g_object_ref (snippet));
|
||||
return snippet;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_color_state_update_uniforms (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
CoglPipeline *pipeline)
|
||||
{
|
||||
ClutterColorStateClass *color_state_class =
|
||||
CLUTTER_COLOR_STATE_GET_CLASS (color_state);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_COLOR_STATE (color_state));
|
||||
g_return_if_fail (CLUTTER_IS_COLOR_STATE (target_color_state));
|
||||
|
||||
color_state_class->update_uniforms (color_state,
|
||||
target_color_state,
|
||||
pipeline);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_color_state_do_transform (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
const float *input,
|
||||
float *output,
|
||||
int n_samples)
|
||||
{
|
||||
ClutterColorStateClass *color_state_class =
|
||||
CLUTTER_COLOR_STATE_GET_CLASS (color_state);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_COLOR_STATE (color_state));
|
||||
g_return_if_fail (CLUTTER_IS_COLOR_STATE (target_color_state));
|
||||
|
||||
color_state_class->do_transform (color_state,
|
||||
target_color_state,
|
||||
input,
|
||||
output,
|
||||
n_samples);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_color_state_add_pipeline_transform (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
CoglPipeline *pipeline)
|
||||
{
|
||||
g_autoptr (CoglSnippet) snippet = NULL;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_COLOR_STATE (color_state));
|
||||
g_return_if_fail (CLUTTER_IS_COLOR_STATE (target_color_state));
|
||||
|
||||
if (clutter_color_state_equals (color_state, target_color_state))
|
||||
return;
|
||||
|
||||
snippet = clutter_color_state_get_transform_snippet (color_state,
|
||||
target_color_state);
|
||||
cogl_pipeline_add_snippet (pipeline, snippet);
|
||||
|
||||
clutter_color_state_update_uniforms (color_state,
|
||||
target_color_state,
|
||||
pipeline);
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_color_state_equals (ClutterColorState *color_state,
|
||||
ClutterColorState *other_color_state)
|
||||
{
|
||||
ClutterColorStateClass *color_state_class =
|
||||
CLUTTER_COLOR_STATE_GET_CLASS (color_state);
|
||||
|
||||
if (color_state == other_color_state)
|
||||
return TRUE;
|
||||
|
||||
if (color_state == NULL || other_color_state == NULL)
|
||||
return FALSE;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_COLOR_STATE (color_state), FALSE);
|
||||
g_return_val_if_fail (CLUTTER_IS_COLOR_STATE (other_color_state), FALSE);
|
||||
|
||||
if (G_OBJECT_TYPE (color_state) != G_OBJECT_TYPE (other_color_state))
|
||||
return FALSE;
|
||||
|
||||
return color_state_class->equals (color_state, other_color_state);
|
||||
}
|
||||
|
||||
char *
|
||||
clutter_color_state_to_string (ClutterColorState *color_state)
|
||||
{
|
||||
ClutterColorStateClass *color_state_class =
|
||||
CLUTTER_COLOR_STATE_GET_CLASS (color_state);
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_COLOR_STATE (color_state), NULL);
|
||||
|
||||
return color_state_class->to_string (color_state);
|
||||
}
|
||||
|
||||
ClutterEncodingRequiredFormat
|
||||
clutter_color_state_required_format (ClutterColorState *color_state)
|
||||
{
|
||||
|
||||
ClutterColorStateClass *color_state_class =
|
||||
CLUTTER_COLOR_STATE_GET_CLASS (color_state);
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_COLOR_STATE (color_state), FALSE);
|
||||
|
||||
return color_state_class->required_format (color_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_color_state_get_blending:
|
||||
* @color_state: a #ClutterColorState
|
||||
* @force: if a linear variant should be forced
|
||||
*
|
||||
* Retrieves a variant of @color_state that is suitable for blending. This
|
||||
* usually is a variant with linear transfer characteristics. If @color_state
|
||||
* already is a #ClutterColorState suitable for blending, then @color_state is
|
||||
* returned.
|
||||
*
|
||||
* If @force is TRUE then linear transfer characteristics are used always.
|
||||
*
|
||||
* Returns: (transfer full): the #ClutterColorState suitable for blending
|
||||
*/
|
||||
ClutterColorState *
|
||||
clutter_color_state_get_blending (ClutterColorState *color_state,
|
||||
gboolean force)
|
||||
{
|
||||
ClutterColorStateClass *color_state_class =
|
||||
CLUTTER_COLOR_STATE_GET_CLASS (color_state);
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_COLOR_STATE (color_state), FALSE);
|
||||
|
||||
return color_state_class->get_blending (color_state, force);
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2022 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Naveen Kumar <naveen1.kumar@intel.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_COLOR_STATE (clutter_color_state_get_type ())
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterColorState,
|
||||
clutter_color_state,
|
||||
CLUTTER, COLOR_STATE,
|
||||
GObject)
|
||||
|
||||
struct _ClutterColorStateClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* init_color_transform_key) (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
ClutterColorTransformKey *key);
|
||||
|
||||
CoglSnippet * (* create_transform_snippet) (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state);
|
||||
|
||||
void (* update_uniforms) (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
CoglPipeline *pipeline);
|
||||
|
||||
void (* do_transform) (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
const float *input,
|
||||
float *output,
|
||||
int n_samples);
|
||||
|
||||
gboolean (* equals) (ClutterColorState *color_state,
|
||||
ClutterColorState *other_color_state);
|
||||
|
||||
char * (* to_string) (ClutterColorState *color_state);
|
||||
|
||||
ClutterEncodingRequiredFormat (* required_format) (ClutterColorState *color_state);
|
||||
|
||||
ClutterColorState * (* get_blending) (ClutterColorState *color_state,
|
||||
gboolean force);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
char * clutter_color_state_to_string (ClutterColorState *color_state);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
unsigned int clutter_color_state_get_id (ClutterColorState *color_state);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_color_state_add_pipeline_transform (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
CoglPipeline *pipeline);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_color_state_update_uniforms (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
CoglPipeline *pipeline);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_color_state_do_transform (ClutterColorState *color_state,
|
||||
ClutterColorState *target_color_state,
|
||||
const float *input,
|
||||
float *output,
|
||||
int n_samples);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_color_state_equals (ClutterColorState *color_state,
|
||||
ClutterColorState *other_color_state);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterEncodingRequiredFormat clutter_color_state_required_format (ClutterColorState *color_state);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterColorState * clutter_color_state_get_blending (ClutterColorState *color_state,
|
||||
gboolean force);
|
||||
|
||||
G_END_DECLS
|
||||
79
clutter/clutter/clutter-color-static.h
Normal file
79
clutter/clutter/clutter-color-static.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_COLOR_STATIC_H__
|
||||
#define __CLUTTER_COLOR_STATIC_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#define __CLUTTER_COLOR_SYM(x) (clutter_color_get_static (CLUTTER_COLOR_##x))
|
||||
|
||||
#define CLUTTER_COLOR_White (__CLUTTER_COLOR_SYM (WHITE))
|
||||
#define CLUTTER_COLOR_Black (__CLUTTER_COLOR_SYM (BLACK))
|
||||
#define CLUTTER_COLOR_Red (__CLUTTER_COLOR_SYM (RED))
|
||||
#define CLUTTER_COLOR_DarkRed (__CLUTTER_COLOR_SYM (DARK_RED))
|
||||
#define CLUTTER_COLOR_Green (__CLUTTER_COLOR_SYM (GREEN))
|
||||
#define CLUTTER_COLOR_DarkGreen (__CLUTTER_COLOR_SYM (DARK_GREEN))
|
||||
#define CLUTTER_COLOR_Blue (__CLUTTER_COLOR_SYM (BLUE))
|
||||
#define CLUTTER_COLOR_DarkBlue (__CLUTTER_COLOR_SYM (DARK_BLUE))
|
||||
#define CLUTTER_COLOR_Cyan (__CLUTTER_COLOR_SYM (CYAN))
|
||||
#define CLUTTER_COLOR_DarkCyan (__CLUTTER_COLOR_SYM (DARK_CYAN))
|
||||
#define CLUTTER_COLOR_Magenta (__CLUTTER_COLOR_SYM (MAGENTA))
|
||||
#define CLUTTER_COLOR_DarkMagenta (__CLUTTER_COLOR_SYM (DARK_MAGENTA))
|
||||
#define CLUTTER_COLOR_Yellow (__CLUTTER_COLOR_SYM (YELLOW))
|
||||
#define CLUTTER_COLOR_DarkYellow (__CLUTTER_COLOR_SYM (DARK_YELLOW))
|
||||
#define CLUTTER_COLOR_Gray (__CLUTTER_COLOR_SYM (GRAY))
|
||||
#define CLUTTER_COLOR_DarkGray (__CLUTTER_COLOR_SYM (DARK_GRAY))
|
||||
#define CLUTTER_COLOR_LightGray (__CLUTTER_COLOR_SYM (LIGHT_GRAY))
|
||||
|
||||
#define CLUTTER_COLOR_Butter (__CLUTTER_COLOR_SYM (BUTTER))
|
||||
#define CLUTTER_COLOR_LightButter (__CLUTTER_COLOR_SYM (BUTTER_LIGHT))
|
||||
#define CLUTTER_COLOR_DarkButter (__CLUTTER_COLOR_SYM (BUTTER_DARK))
|
||||
#define CLUTTER_COLOR_Orange (__CLUTTER_COLOR_SYM (ORANGE))
|
||||
#define CLUTTER_COLOR_LightOrange (__CLUTTER_COLOR_SYM (ORANGE_LIGHT))
|
||||
#define CLUTTER_COLOR_DarkOrange (__CLUTTER_COLOR_SYM (ORANGE_DARK))
|
||||
#define CLUTTER_COLOR_Chocolate (__CLUTTER_COLOR_SYM (CHOCOLATE))
|
||||
#define CLUTTER_COLOR_LightChocolate (__CLUTTER_COLOR_SYM (CHOCOLATE_LIGHT))
|
||||
#define CLUTTER_COLOR_DarkChocolate (__CLUTTER_COLOR_SYM (CHOCOLATE_DARK))
|
||||
#define CLUTTER_COLOR_Chameleon (__CLUTTER_COLOR_SYM (CHAMELEON))
|
||||
#define CLUTTER_COLOR_LightChameleon (__CLUTTER_COLOR_SYM (CHAMELEON_LIGHT))
|
||||
#define CLUTTER_COLOR_DarkChameleon (__CLUTTER_COLOR_SYM (CHAMELEON_DARK))
|
||||
#define CLUTTER_COLOR_SkyBlue (__CLUTTER_COLOR_SYM (SKY_BLUE))
|
||||
#define CLUTTER_COLOR_LightSkyBlue (__CLUTTER_COLOR_SYM (SKY_BLUE_LIGHT))
|
||||
#define CLUTTER_COLOR_DarkSkyBlue (__CLUTTER_COLOR_SYM (SKY_BLUE_DARK))
|
||||
#define CLUTTER_COLOR_Plum (__CLUTTER_COLOR_SYM (PLUM))
|
||||
#define CLUTTER_COLOR_LightPlum (__CLUTTER_COLOR_SYM (PLUM_LIGHT))
|
||||
#define CLUTTER_COLOR_DarkPlum (__CLUTTER_COLOR_SYM (PLUM_DARK))
|
||||
#define CLUTTER_COLOR_ScarletRed (__CLUTTER_COLOR_SYM (SCARLET_RED))
|
||||
#define CLUTTER_COLOR_LightScarletRed (__CLUTTER_COLOR_SYM (SCARLET_RED_LIGHT))
|
||||
#define CLUTTER_COLOR_DarkScarletRed (__CLUTTER_COLOR_SYM (SCARLET_RED_DARK))
|
||||
#define CLUTTER_COLOR_Aluminium1 (__CLUTTER_COLOR_SYM (ALUMINIUM_1))
|
||||
#define CLUTTER_COLOR_Aluminium2 (__CLUTTER_COLOR_SYM (ALUMINIUM_2))
|
||||
#define CLUTTER_COLOR_Aluminium3 (__CLUTTER_COLOR_SYM (ALUMINIUM_3))
|
||||
#define CLUTTER_COLOR_Aluminium4 (__CLUTTER_COLOR_SYM (ALUMINIUM_4))
|
||||
#define CLUTTER_COLOR_Aluminium5 (__CLUTTER_COLOR_SYM (ALUMINIUM_5))
|
||||
#define CLUTTER_COLOR_Aluminium6 (__CLUTTER_COLOR_SYM (ALUMINIUM_6))
|
||||
|
||||
#define CLUTTER_COLOR_Transparent (__CLUTTER_COLOR_SYM (TRANSPARENT))
|
||||
|
||||
#endif /* __CLUTTER_COLOR_STATIC_H__ */
|
||||
1193
clutter/clutter/clutter-color.c
Normal file
1193
clutter/clutter/clutter-color.c
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user