Compare commits
1 Commits
main
...
wip/smcv/c
Author | SHA1 | Date | |
---|---|---|---|
2efd0dfc06 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -103,4 +103,3 @@ doc/reference/meta.types
|
||||
.dirstamp
|
||||
**/tags.*
|
||||
build/
|
||||
subprojects/sysprof/
|
||||
|
379
.gitlab-ci.yml
379
.gitlab-ci.yml
@ -1,382 +1,111 @@
|
||||
include:
|
||||
- remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/bbe5232986c9b98eb1efe62484e07216f7d1a4df/templates/fedora.yml'
|
||||
- remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/bbe5232986c9b98eb1efe62484e07216f7d1a4df/templates/ci-fairy.yml'
|
||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v4
|
||||
|
||||
stages:
|
||||
- review
|
||||
- prepare
|
||||
- code-review
|
||||
- build
|
||||
- test
|
||||
- analyze
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
FDO_UPSTREAM_REPO: GNOME/mutter
|
||||
|
||||
.mutter.fedora:34@common:
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: 34
|
||||
BASE_TAG: '2021-09-15.0'
|
||||
FDO_DISTRIBUTION_PACKAGES:
|
||||
asciidoc
|
||||
clang
|
||||
gcovr
|
||||
gdm
|
||||
gnome-shell
|
||||
python3-dbusmock
|
||||
sassc
|
||||
uncrustify
|
||||
xorg-x11-server-Xvfb
|
||||
|
||||
FDO_DISTRIBUTION_EXEC: |
|
||||
dnf install -y 'dnf-command(builddep)' &&
|
||||
|
||||
dnf builddep -y mutter --setopt=install_weak_deps=False &&
|
||||
dnf builddep -y gnome-shell --setopt=install_weak_deps=False &&
|
||||
dnf builddep -y libinput --setopt=install_weak_deps=False &&
|
||||
dnf builddep -y wayland-protocols --setopt=install_weak_deps=False &&
|
||||
|
||||
./.gitlab-ci/install-meson-project.sh \
|
||||
https://gitlab.gnome.org/GNOME/glib.git \
|
||||
main . 02742ef957b532789c003eef80ec7f51c370e3d5 &&
|
||||
|
||||
./.gitlab-ci/install-meson-project.sh \
|
||||
https://gitlab.gnome.org/GNOME/gsettings-desktop-schemas.git \
|
||||
41.alpha . &&
|
||||
|
||||
./.gitlab-ci/install-meson-project.sh \
|
||||
https://gitlab.gnome.org/GNOME/gjs.git \
|
||||
1.69.2 . &&
|
||||
|
||||
./.gitlab-ci/install-meson-project.sh \
|
||||
https://gitlab.freedesktop.org/libinput/libinput.git \
|
||||
1.19.0 . &&
|
||||
|
||||
./.gitlab-ci/install-meson-project.sh \
|
||||
https://gitlab.freedesktop.org/wayland/wayland-protocols.git \
|
||||
1.23 . &&
|
||||
|
||||
rpm -e --nodeps gnome-bluetooth-libs-devel \
|
||||
mutter mutter-devel \
|
||||
gnome-shell &&
|
||||
|
||||
dnf clean all
|
||||
|
||||
default:
|
||||
# Cancel jobs if newer commits are pushed to the branch
|
||||
interruptible: true
|
||||
# Auto-retry jobs in case of infra failures
|
||||
retry:
|
||||
max: 1
|
||||
when:
|
||||
- 'runner_system_failure'
|
||||
- 'stuck_or_timeout_failure'
|
||||
- 'scheduler_failure'
|
||||
- 'api_failure'
|
||||
|
||||
.mutter.fedora:34@x86_64:
|
||||
extends: .mutter.fedora:34@common
|
||||
variables:
|
||||
FDO_DISTRIBUTION_TAG: "x86_64-${BASE_TAG}"
|
||||
|
||||
.mutter.fedora:34@aarch64:
|
||||
extends: .mutter.fedora:34@common
|
||||
variables:
|
||||
FDO_DISTRIBUTION_TAG: "aarch64-${BASE_TAG}"
|
||||
tags:
|
||||
- aarch64
|
||||
|
||||
workflow:
|
||||
rules:
|
||||
- if: '$CI_MERGE_REQUEST_IID'
|
||||
- if: '$CI_COMMIT_TAG'
|
||||
- if: '$CI_COMMIT_BRANCH'
|
||||
|
||||
.pipline-guard: &pipline-guard
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
- if: '$CI_COMMIT_TAG'
|
||||
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
||||
- if: '$CI_COMMIT_BRANCH =~ /^gnome-[0-9-]+$/'
|
||||
- when: 'manual'
|
||||
- coverage
|
||||
|
||||
check-commit-log:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
stage: review
|
||||
variables:
|
||||
GIT_DEPTH: "100"
|
||||
script:
|
||||
- if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ;
|
||||
then
|
||||
ci-fairy check-commits --junit-xml=commit-message-junit-report.xml ;
|
||||
else
|
||||
echo "Not a merge request" ;
|
||||
fi
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- commit-message-junit-report.xml
|
||||
reports:
|
||||
junit: commit-message-junit-report.xml
|
||||
<<: *pipline-guard
|
||||
- ./.gitlab-ci/check-commit-log.sh
|
||||
only:
|
||||
- merge_requests
|
||||
|
||||
check-merge-request:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
stage: review
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
script:
|
||||
- if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ;
|
||||
then
|
||||
ci-fairy check-merge-request --require-allow-collaboration --junit-xml=check-merge-request-report.xml ;
|
||||
else
|
||||
echo "Not a merge request" ;
|
||||
fi
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- check-merge-request-report.xml
|
||||
reports:
|
||||
junit: check-merge-request-report.xml
|
||||
<<: *pipline-guard
|
||||
|
||||
build-fedora-container@x86_64:
|
||||
extends:
|
||||
- .fdo.container-build@fedora@x86_64
|
||||
- .mutter.fedora:34@x86_64
|
||||
stage: prepare
|
||||
needs:
|
||||
- check-commit-log
|
||||
- check-merge-request
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
|
||||
build-fedora-container@aarch64:
|
||||
extends:
|
||||
- .fdo.container-build@fedora@aarch64
|
||||
- .mutter.fedora:34@aarch64
|
||||
stage: prepare
|
||||
needs:
|
||||
- check-commit-log
|
||||
- check-merge-request
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
|
||||
check-code-style:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
- .mutter.fedora:34@x86_64
|
||||
stage: code-review
|
||||
needs:
|
||||
- build-fedora-container@x86_64
|
||||
script:
|
||||
- if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ;
|
||||
then
|
||||
git remote add target $CI_MERGE_REQUEST_PROJECT_URL.git ;
|
||||
git fetch target $CI_MERGE_REQUEST_TARGET_BRANCH_NAME ;
|
||||
export common_parent_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "target/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME") <(git rev-list --first-parent HEAD) | head -1) ;
|
||||
python3 -u ./check-style.py --dry-run --sha $common_parent_sha ;
|
||||
else
|
||||
echo "Not a merge request" ;
|
||||
fi
|
||||
allow_failure: true
|
||||
|
||||
.build-mutter:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
build-mutter:
|
||||
stage: build
|
||||
script:
|
||||
- meson . build -Dbuildtype=debugoptimized -Db_coverage=true -Degl_device=true -Dwayland_eglstream=true --werror --prefix /usr
|
||||
- meson compile -C build
|
||||
- meson install -C build
|
||||
- ninja -C build
|
||||
- ninja -C build install
|
||||
artifacts:
|
||||
expire_in: 1 day
|
||||
paths:
|
||||
- build
|
||||
only:
|
||||
- merge_requests
|
||||
- /^.*$/
|
||||
|
||||
build-mutter@x86_64:
|
||||
extends:
|
||||
- .build-mutter
|
||||
- .mutter.fedora:34@x86_64
|
||||
needs:
|
||||
- build-fedora-container@x86_64
|
||||
|
||||
build-mutter@aarch64:
|
||||
extends:
|
||||
- .build-mutter
|
||||
- .mutter.fedora:34@aarch64
|
||||
needs:
|
||||
- build-fedora-container@aarch64
|
||||
|
||||
build-without-opengl-and-glx@x86_64:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
- .mutter.fedora:34@x86_64
|
||||
build-without-opengl-and-glx:
|
||||
stage: build
|
||||
needs:
|
||||
- build-fedora-container@x86_64
|
||||
script:
|
||||
- meson . build -Dbuildtype=debugoptimized -Dopengl=false -Dglx=false -Degl_device=true -Dwayland_eglstream=true --werror --prefix /usr
|
||||
- meson compile -C build
|
||||
- meson install -C build
|
||||
- ninja -C build
|
||||
- ninja -C build install
|
||||
artifacts:
|
||||
paths:
|
||||
- build/meson-logs
|
||||
only:
|
||||
- merge_requests
|
||||
- /^.*$/
|
||||
|
||||
build-without-native-backend-and-wayland@x86_64:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
- .mutter.fedora:34@x86_64
|
||||
build-without-native-backend-and-wayland:
|
||||
stage: build
|
||||
needs:
|
||||
- build-fedora-container@x86_64
|
||||
script:
|
||||
- meson . build -Dbuildtype=debugoptimized -Dnative_backend=false -Dudev=false -Dwayland=false -Dcore_tests=false -Dnative_tests=false --werror --prefix /usr
|
||||
- meson compile -C build
|
||||
- meson install -C build
|
||||
- meson . build -Dbuildtype=debugoptimized -Dnative_backend=false -Dudev=false -Dwayland=false -Dcore_tests=false --werror --prefix /usr
|
||||
- ninja -C build
|
||||
- ninja -C build install
|
||||
artifacts:
|
||||
paths:
|
||||
- build/meson-logs
|
||||
only:
|
||||
- merge_requests
|
||||
- /^.*$/
|
||||
|
||||
.test-setup: &test-setup
|
||||
test-mutter:
|
||||
stage: test
|
||||
dependencies:
|
||||
- build-mutter
|
||||
variables:
|
||||
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
|
||||
GSETTINGS_SCHEMA_DIR: "$CI_PROJECT_DIR/build/data"
|
||||
MUTTER_DEBUG_DUMMY_MODE_SPECS: "800x600@10.0"
|
||||
PIPEWIRE_DEBUG: 2
|
||||
PIPEWIRE_LOG: "$CI_PROJECT_DIR/build/meson-logs/pipewire.log"
|
||||
XVFB_SERVER_ARGS: "+iglx -noreset"
|
||||
G_SLICE: "always-malloc"
|
||||
MALLOC_CHECK_: "3"
|
||||
NO_AT_BRIDGE: "1"
|
||||
before_script:
|
||||
- glib-compile-schemas $GSETTINGS_SCHEMA_DIR
|
||||
# Disable e.g. audio support to not dead lock screen cast tests
|
||||
- rm -f /usr/share/pipewire/media-session.d/with-*
|
||||
- mkdir -m 700 $XDG_RUNTIME_DIR
|
||||
- pipewire & sleep 2
|
||||
|
||||
.test-mutter:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
<<: *test-setup
|
||||
stage: test
|
||||
script:
|
||||
- dbus-run-session -- xvfb-run -a -s "$XVFB_SERVER_ARGS"
|
||||
catchsegv meson test -C build --no-rebuild -t 10
|
||||
- dconf update
|
||||
- mkdir -m 700 $XDG_RUNTIME_DIR
|
||||
- glib-compile-schemas $GSETTINGS_SCHEMA_DIR
|
||||
- >
|
||||
dbus-run-session -- xvfb-run -s '+iglx -noreset'
|
||||
meson test -C build --no-rebuild -t 10 --verbose --no-stdsplit --print-errorlogs --wrap catchsegv
|
||||
artifacts:
|
||||
expire_in: 1 day
|
||||
reports:
|
||||
junit: "build/meson-logs/testlog.junit.xml"
|
||||
name: "mutter-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
|
||||
when: always
|
||||
paths:
|
||||
- build
|
||||
only:
|
||||
- merge_requests
|
||||
- /^.*$/
|
||||
|
||||
test-mutter@x86_64:
|
||||
extends:
|
||||
- .test-mutter
|
||||
- .mutter.fedora:34@x86_64
|
||||
needs:
|
||||
- build-mutter@x86_64
|
||||
|
||||
test-mutter@aarch64:
|
||||
extends:
|
||||
- .test-mutter
|
||||
- .mutter.fedora:34@aarch64
|
||||
needs:
|
||||
- build-mutter@aarch64
|
||||
|
||||
.test-mutter-coverage:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
stage: analyze
|
||||
test-mutter-coverage:
|
||||
stage: coverage
|
||||
dependencies:
|
||||
- test-mutter
|
||||
script:
|
||||
- ninja -C build coverage
|
||||
- cat build/meson-logs/coverage.txt
|
||||
artifacts:
|
||||
paths:
|
||||
- build/meson-logs/coveragereport
|
||||
coverage: '/^TOTAL.*\s+(\d+\%)$/'
|
||||
- build/meson-logs
|
||||
when: manual
|
||||
except:
|
||||
refs:
|
||||
- tags
|
||||
- master
|
||||
|
||||
test-mutter-coverage@x86_64:
|
||||
extends:
|
||||
- .test-mutter-coverage
|
||||
- .mutter.fedora:34@x86_64
|
||||
needs:
|
||||
- test-mutter@x86_64
|
||||
|
||||
test-mutter-coverage@aarch64:
|
||||
extends:
|
||||
- .test-mutter-coverage
|
||||
- .mutter.fedora:34@aarch64
|
||||
needs:
|
||||
- test-mutter@aarch64
|
||||
|
||||
can-build-gnome-shell@x86_64:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
- .mutter.fedora:34@x86_64
|
||||
can-build-gnome-shell:
|
||||
stage: test
|
||||
needs:
|
||||
- build-mutter@x86_64
|
||||
dependencies:
|
||||
- build-mutter
|
||||
before_script:
|
||||
- meson install --no-rebuild -C build
|
||||
script:
|
||||
- .gitlab-ci/checkout-gnome-shell.sh
|
||||
- meson gnome-shell gnome-shell/build --prefix /usr -Dman=false
|
||||
- meson install -C gnome-shell/build
|
||||
|
||||
test-mutter-coverity:
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "schedule" && $MUTTER_SCHEDULED_JOB == "coverity"'
|
||||
when: always
|
||||
- when: manual
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
- .mutter.fedora:34@x86_64
|
||||
needs:
|
||||
- build-fedora-container@x86_64
|
||||
stage: analyze
|
||||
allow_failure: true
|
||||
script:
|
||||
- .gitlab-ci/download-coverity-tarball.sh
|
||||
- CC=clang meson coverity-build -Dprofiler=false
|
||||
- ./coverity/cov-analysis-linux64-*/bin/cov-build --dir cov-int meson compile -C coverity-build
|
||||
- tar czf cov-int.tar.gz cov-int
|
||||
- curl https://scan.coverity.com/builds?project=mutter
|
||||
--form token=$COVERITY_TOKEN --form email=carlosg@gnome.org
|
||||
--form file=@cov-int.tar.gz --form version="`git describe --tags`"
|
||||
--form description="GitLab CI build"
|
||||
cache:
|
||||
key: coverity-tarball
|
||||
paths:
|
||||
- coverity
|
||||
|
||||
dist-mutter:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
- .mutter.fedora:34@x86_64
|
||||
<<: *test-setup
|
||||
stage: deploy
|
||||
needs:
|
||||
- build-mutter@x86_64
|
||||
script:
|
||||
- dbus-run-session -- xvfb-run -a -s "$XVFB_SERVER_ARGS" meson dist -C build
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
changes:
|
||||
- "**/meson.build"
|
||||
- meson/*
|
||||
|
||||
dist-mutter-tarball:
|
||||
extends: dist-mutter
|
||||
artifacts:
|
||||
expose_as: 'Get tarball here'
|
||||
paths:
|
||||
- build/meson-dist/$CI_PROJECT_NAME-$CI_COMMIT_TAG.tar.xz
|
||||
rules:
|
||||
- if: '$CI_COMMIT_TAG'
|
||||
- ninja -C gnome-shell/build install
|
||||
only:
|
||||
- merge_requests
|
||||
- /^.*$/
|
||||
|
27
.gitlab-ci/Dockerfile
Normal file
27
.gitlab-ci/Dockerfile
Normal file
@ -0,0 +1,27 @@
|
||||
# Rebuild and push with
|
||||
#
|
||||
# cd .gitlab-ci/
|
||||
# podman build --format docker --no-cache -t registry.gitlab.gnome.org/gnome/mutter/master:v4 .
|
||||
# podman push registry.gitlab.gnome.org/gnome/mutter/master:v4
|
||||
#
|
||||
|
||||
FROM fedora:32
|
||||
|
||||
RUN dnf -y update && dnf -y upgrade && \
|
||||
dnf install -y 'dnf-command(builddep)' && \
|
||||
dnf install -y 'dnf-command(copr)' && \
|
||||
dnf copr enable -y jadahl/mutter-ci && \
|
||||
|
||||
dnf builddep -y mutter --setopt=install_weak_deps=False && \
|
||||
|
||||
# For running unit tests
|
||||
dnf install -y xorg-x11-server-Xvfb mesa-dri-drivers dbus dbus-x11 \
|
||||
'*/xvfb-run' gdm-lib accountsservice-libs gnome-control-center gcovr \
|
||||
--setopt=install_weak_deps=False && \
|
||||
|
||||
# GNOME Shell
|
||||
dnf builddep -y gnome-shell --setopt=install_weak_deps=False && \
|
||||
dnf remove -y gnome-bluetooth-libs-devel && \
|
||||
dnf remove -y --noautoremove mutter mutter-devel && \
|
||||
|
||||
dnf clean all
|
60
.gitlab-ci/check-commit-log.sh
Executable file
60
.gitlab-ci/check-commit-log.sh
Executable file
@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ -z "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
|
||||
echo Cannot review non-merge request
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git fetch $CI_MERGE_REQUEST_PROJECT_URL.git $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
|
||||
|
||||
branch_point=$(git merge-base HEAD FETCH_HEAD)
|
||||
|
||||
commits=$(git log --format='format:%H' $branch_point..$CI_COMMIT_SHA)
|
||||
|
||||
if [ -z "$commits" ]; then
|
||||
echo Commit range empty
|
||||
exit 1
|
||||
fi
|
||||
|
||||
function commit_message_has_url() {
|
||||
commit=$1
|
||||
commit_message=$(git show -s --format='format:%b' $commit)
|
||||
echo "$commit_message" | grep -qe "\($CI_MERGE_REQUEST_PROJECT_URL/\(-/\)\?\(issues\|merge_requests\)/[0-9]\+\|https://bugzilla.gnome.org/show_bug.cgi?id=[0-9]\+\)"
|
||||
return $?
|
||||
}
|
||||
|
||||
function commit_message_subject_is_compliant() {
|
||||
commit=$1
|
||||
commit_message_subject=$(git show -s --format='format:%s' $commit)
|
||||
|
||||
if echo "$commit_message_subject" | grep -qe "\(^meta-\|^Meta\)"; then
|
||||
echo " - message subject should not be prefixed with 'meta-' or 'Meta'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if echo "$commit_message_subject" | grep -qe "\.[ch]:"; then
|
||||
echo " - message subject prefix should not include .c, .h, etc."
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
RET=0
|
||||
for commit in $commits; do
|
||||
commit_short=$(echo $commit | cut -c -8)
|
||||
|
||||
if ! commit_message_has_url $commit; then
|
||||
echo "Commit $commit_short needs a merge request or issue URL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
errors=$(commit_message_subject_is_compliant $commit)
|
||||
if [ $? != 0 ]; then
|
||||
echo "Commit message for $commit_short is not compliant:"
|
||||
echo "$errors"
|
||||
RET=1
|
||||
fi
|
||||
done
|
||||
|
||||
exit $RET
|
@ -1,19 +1,11 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
fetch() {
|
||||
local remote=$1
|
||||
local ref=$2
|
||||
|
||||
git fetch --quiet --depth=1 $remote $ref 2>/dev/null
|
||||
}
|
||||
|
||||
gnome_shell_target=
|
||||
|
||||
echo -n Cloning into gnome-shell ...
|
||||
if git clone --quiet --depth=1 https://gitlab.gnome.org/GNOME/gnome-shell.git; then
|
||||
echo \ done
|
||||
else
|
||||
echo \ failed
|
||||
git clone https://gitlab.gnome.org/GNOME/gnome-shell.git
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo Checkout failed
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@ -23,33 +15,19 @@ if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
|
||||
merge_request_remote=${CI_MERGE_REQUEST_SOURCE_PROJECT_URL//mutter/gnome-shell}
|
||||
merge_request_branch=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
|
||||
|
||||
echo -n Looking for $merge_request_branch on remote ...
|
||||
if fetch $merge_request_remote $merge_request_branch; then
|
||||
echo \ found
|
||||
echo Looking for $merge_request_branch on remote ...
|
||||
if git fetch -q $merge_request_remote $merge_request_branch 2>/dev/null; then
|
||||
gnome_shell_target=FETCH_HEAD
|
||||
else
|
||||
echo \ not found
|
||||
|
||||
echo -n Looking for $CI_MERGE_REQUEST_TARGET_BRANCH_NAME instead ...
|
||||
if fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME; then
|
||||
echo \ found
|
||||
gnome_shell_target=FETCH_HEAD
|
||||
else
|
||||
echo \ not found
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$gnome_shell_target" ]; then
|
||||
echo -n Looking for $CI_COMMIT_REF_NAME on remote ...
|
||||
if fetch origin $CI_COMMIT_REF_NAME; then
|
||||
echo \ found
|
||||
gnome_shell_target=FETCH_HEAD
|
||||
else
|
||||
echo \ not found
|
||||
gnome_shell_target=HEAD
|
||||
gnome_shell_target=origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
|
||||
echo Using $gnome_shell_target instead
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$gnome_shell_target" ]; then
|
||||
gnome_shell_target=$(git branch -r -l origin/$CI_COMMIT_REF_NAME)
|
||||
gnome_shell_target=${gnome_shell_target:-origin/master}
|
||||
echo Using $gnome_shell_target instead
|
||||
fi
|
||||
|
||||
git checkout -q $gnome_shell_target
|
||||
|
@ -1,19 +0,0 @@
|
||||
patterns:
|
||||
deny:
|
||||
- regex: '^$CI_MERGE_REQUEST_PROJECT_URL/(-/)?merge_requests/$CI_MERGE_REQUEST_IID$'
|
||||
message: Commit message must not contain a link to its own merge request
|
||||
- regex: '^(meta-|Meta)'
|
||||
message: Commit message subject should not be prefixed with 'meta-' or 'Meta'
|
||||
where: subject
|
||||
- regex: '^(clutter-|Clutter)'
|
||||
message: Commit message subject should not be prefixed with 'clutter-' or 'Clutter', use 'clutter/' instead
|
||||
where: subject
|
||||
- regex: '^(cogl-|Cogl)'
|
||||
message: Commit message subject should not be prefixed with 'cogl-' or 'Cogl', use 'cogl/' instead
|
||||
where: subject
|
||||
- regex: '^[^:]+: [a-z]'
|
||||
message: "Commit message subject should be properly Capitalized. E.g. 'window: Marginalize extradicity'"
|
||||
where: subject
|
||||
- regex: '^\S*\.[ch]:'
|
||||
message: Commit message subject prefix should not include .c, .h, etc.
|
||||
where: subject
|
@ -1,38 +0,0 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
# We need a coverity token to fetch the tarball
|
||||
if [ -x $COVERITY_TOKEN ]
|
||||
then
|
||||
echo "No coverity token. Run this job from a protected branch."
|
||||
exit -1
|
||||
fi
|
||||
|
||||
mkdir -p coverity
|
||||
|
||||
# Download and check MD5 first
|
||||
curl https://scan.coverity.com/download/linux64 \
|
||||
--data "token=$COVERITY_TOKEN&project=mutter&md5=1" \
|
||||
--output /tmp/coverity_tool.md5
|
||||
|
||||
diff /tmp/coverity_tool.md5 coverity/coverity_tool.md5 >/dev/null 2>&1
|
||||
|
||||
if [ $? -eq 0 -a -d coverity/cov-analysis* ]
|
||||
then
|
||||
echo "Coverity tarball is up-to-date"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Download and extract coverity tarball
|
||||
curl https://scan.coverity.com/download/linux64 \
|
||||
--data "token=$COVERITY_TOKEN&project=mutter" \
|
||||
--output /tmp/coverity_tool.tgz
|
||||
|
||||
rm -rf ./coverity/cov-analysis*
|
||||
|
||||
tar zxf /tmp/coverity_tool.tgz -C coverity/
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
mv /tmp/coverity_tool.md5 coverity/
|
||||
fi
|
||||
|
||||
rm /tmp/coverity_tool.tgz
|
@ -1,39 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
if [[ $# -lt 3 ]]; then
|
||||
echo Usage: $0 [options] [repo-url] [commit] [subdir]
|
||||
echo Options:
|
||||
echo -Dkey=val
|
||||
exit 1
|
||||
fi
|
||||
|
||||
MESON_OPTIONS=()
|
||||
|
||||
while [[ $1 =~ ^-D ]]; do
|
||||
MESON_OPTIONS+=( "$1" )
|
||||
shift
|
||||
done
|
||||
|
||||
REPO_URL="$1"
|
||||
TAG_OR_BRANCH="$2"
|
||||
SUBDIR="$3"
|
||||
COMMIT="$4"
|
||||
|
||||
REPO_DIR="$(basename ${REPO_URL%.git})"
|
||||
|
||||
git clone --depth 1 "$REPO_URL" -b "$TAG_OR_BRANCH"
|
||||
pushd "$REPO_DIR"
|
||||
pushd "$SUBDIR"
|
||||
|
||||
if [ ! -z "$COMMIT" ]; then
|
||||
git fetch origin "$COMMIT"
|
||||
git checkout "$COMMIT"
|
||||
fi
|
||||
|
||||
meson --prefix=/usr _build "${MESON_OPTIONS[@]}"
|
||||
meson install -C _build
|
||||
popd
|
||||
popd
|
||||
rm -rf "$REPO_DIR"
|
286
HACKING.md
286
HACKING.md
@ -1,286 +0,0 @@
|
||||
# Style
|
||||
|
||||
The coding style used is primarily the GNU flavor of the [GNOME coding
|
||||
style][gnome-coding-style], with some additions described below.
|
||||
|
||||
## General
|
||||
|
||||
* Use this code style on new code. When changing old code with a different
|
||||
code style, feel free to also adjust it to use this code style.
|
||||
|
||||
* Use regular C types and `stdint.h` types instead of GLib fundamental
|
||||
types, except for `gboolean`, and `guint`/`gulong` for GSource IDs and
|
||||
signal handler IDs. That means e.g. `uint64_t` instead of `guint64`, `int`
|
||||
instead of `gint`, `unsigned int` instead of `guint` if unsignedness
|
||||
is of importance, `uint8_t` instead of `guchar`, and so on.
|
||||
|
||||
* Try to to limit line length to 80 characters, although it's not a
|
||||
strict limit.
|
||||
|
||||
* Usage of `g_autofree` and `g_autoptr` is encouraged. The style to use is
|
||||
|
||||
```c
|
||||
g_autofree char *text = NULL;
|
||||
g_autoptr (MetaSomeThing) thing = NULL;
|
||||
|
||||
text = g_strdup_printf ("The text: %d", a_number);
|
||||
thing = g_object_new (META_TYPE_SOME_THING,
|
||||
"text", text,
|
||||
NULL);
|
||||
thinger_use_thing (rocket, thing);
|
||||
```
|
||||
|
||||
* Declare variables at the top of the block they are used, but avoid
|
||||
non-trivial logic among variable declarations. Non-trivial logic can be
|
||||
getting a pointer that may be `NULL`, any kind of math, or anything
|
||||
that may have side effects.
|
||||
|
||||
* Instead of boolean arguments in functions, prefer enums or flags when
|
||||
they're more expressive. The naming convention for flags is
|
||||
|
||||
```c
|
||||
typedef _MetaSomeThingFlags
|
||||
{
|
||||
META_SOME_THING_FLAG_NONE = 0,
|
||||
META_SOME_THING_FLAG_ALTER_REALITY = 1 << 0,
|
||||
META_SOME_THING_FLAG_MANIPULATE_PERCEPTION = 1 << 1,
|
||||
} MetaSomeThingFlags;
|
||||
```
|
||||
|
||||
* Use `g_new0 ()` etc. instead of `g_slice_new0 ()`.
|
||||
|
||||
* Initialize and assign floating point variables (i.e. `float` or
|
||||
`double`) using the form `floating_point = 3.14159` or `ratio = 2.0`.
|
||||
|
||||
## Header (.h) files
|
||||
|
||||
* The return type and `*` are separated by a space.
|
||||
* Function name starts one space after the last `*`.
|
||||
* Parenthesis comes one space after the function name.
|
||||
|
||||
As an example, this is how functions in a header file should look like:
|
||||
|
||||
```c
|
||||
gboolean meta_udev_is_drm_device (MetaUdev *udev,
|
||||
GUdevDevice *device);
|
||||
|
||||
GList * meta_udev_list_drm_devices (MetaUdev *udev,
|
||||
GError **error);
|
||||
|
||||
MetaUdev * meta_udev_new (MetaBackendNative *backend_native);
|
||||
```
|
||||
|
||||
## Source code
|
||||
|
||||
Keep functions in the following order in source files:
|
||||
|
||||
1. GPL header
|
||||
2. Enums
|
||||
3. Structures
|
||||
4. Function prototypes
|
||||
5. `G_DEFINE_TYPE()`
|
||||
6. Static variables
|
||||
7. Auxiliary functions
|
||||
8. Callbacks
|
||||
9. Interface implementations
|
||||
10. Parent vfunc overrides
|
||||
11. class_init and init
|
||||
12. Public API
|
||||
|
||||
### Structures
|
||||
|
||||
Each structure field has a space after their type name. Structure fields aren't
|
||||
aligned. For example:
|
||||
|
||||
```c
|
||||
struct _MetaFooBar
|
||||
{
|
||||
MetaFoo parent;
|
||||
|
||||
MetaBar *bar;
|
||||
MetaSomething *something;
|
||||
};
|
||||
```
|
||||
|
||||
### Function Prototypes
|
||||
|
||||
Function prototypes must be formatted just like in header files.
|
||||
|
||||
### Overrides
|
||||
|
||||
When overriding parent class vfuncs, or implementing an interface, vfunc
|
||||
overrides should be named as a composition of the current class prefix,
|
||||
followed by the vfunc name. For example:
|
||||
|
||||
|
||||
```c
|
||||
static void
|
||||
meta_bar_spawn_unicorn (MetaParent *parent)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
static void
|
||||
meta_bar_dispose (GObject *object)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
static void
|
||||
meta_bar_finalize (GObject *object)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
static void
|
||||
meta_bar_class_init (MetaBarClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
MetaParentClass *parent_class = META_PARENT_CLASS (klass);
|
||||
|
||||
object_class->dispose = meta_bar_dispose;
|
||||
object_class->finalize = meta_bar_finalize;
|
||||
|
||||
parent_class->spawn_unicorn = meta_bar_spawn_unicorn;
|
||||
}
|
||||
```
|
||||
|
||||
### Interface Implementations
|
||||
|
||||
When implementing interfaces, two groups of functions are involved: the init
|
||||
function, and the overrides.
|
||||
|
||||
The interface init function is named after the interface type in snake case,
|
||||
followed by the `_iface_init` suffix. For example:
|
||||
|
||||
|
||||
```c
|
||||
static void meta_foo_iface_init (MetaFooInterface *foo_iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaBar, meta_bar, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (META_TYPE_FOO,
|
||||
meta_foo_iface_init));
|
||||
```
|
||||
|
||||
Then, when implementing each vfunc of the interface, follow the same pattern
|
||||
of the [Overrides](###Overrides) section. Here's an example:
|
||||
|
||||
```c
|
||||
static void
|
||||
meta_bar_do_something (MetaFoo *foo)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
static void
|
||||
meta_foo_iface_init (MetaFooInterface *foo_iface)
|
||||
{
|
||||
foo_iface->do_something = meta_bar_do_something;
|
||||
}
|
||||
```
|
||||
|
||||
### Auxiliary Functions
|
||||
|
||||
Auxiliary functions are above every other functions to minimize the number of
|
||||
function prototypes in the file. These functions often grow when factoring out
|
||||
the same code between two or more functions:
|
||||
|
||||
```c
|
||||
static void
|
||||
do_something_on_data (Foo *data,
|
||||
Bar *bar)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
static void
|
||||
random_function (Foo *foo)
|
||||
{
|
||||
do_something_on_data (foo, bar);
|
||||
}
|
||||
|
||||
static void
|
||||
another_random_function (Foo *foo)
|
||||
{
|
||||
do_something_on_data (foo, bar);
|
||||
}
|
||||
```
|
||||
|
||||
Sometimes, however, auxiliary functions are created to break down otherwise
|
||||
large functions - in this case, it is appropriate to keep these auxiliary
|
||||
functions close to the function they are tightly related to.
|
||||
|
||||
Auxiliary function names must have a verb in the imperative form, and should
|
||||
always perform an action over something. They usually don't have the class
|
||||
prefix (`meta_`, `clutter_`, or `cogl_`). For example:
|
||||
|
||||
```c
|
||||
static void
|
||||
do_something_on_data (Foo *data,
|
||||
Bar *bar)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
```
|
||||
|
||||
Exceptionally, when converting between types, auxiliary function names may
|
||||
have the class prefix to this rule. For example:
|
||||
|
||||
```c
|
||||
static MetaFoo *
|
||||
meta_foo_from_bar (Bar *bar)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
```
|
||||
|
||||
### Callback Functions
|
||||
|
||||
Callback function names should have the name of the action in imperative
|
||||
form. They don't have any prefix, but have a `_func` suffix. For example:
|
||||
|
||||
```c
|
||||
static void
|
||||
filter_something_func (Foo *foo,
|
||||
Bar *bar,
|
||||
gpointer user_data)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
```
|
||||
|
||||
### Signal Callbacks
|
||||
|
||||
Signal callbacks generally have the signal name. They should be prefixed with
|
||||
`on_`, or suffixed with `_cb`, but not both. For example:
|
||||
|
||||
```c
|
||||
static void
|
||||
on_realize (ClutterActor *actor,
|
||||
gpointer user_data)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_cb (ClutterActor *actor,
|
||||
gpointer user_data)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
```
|
||||
|
||||
When the callback is named after the object that generated it, and the signal,
|
||||
then passive voice is used. For example:
|
||||
|
||||
```c
|
||||
static void
|
||||
click_action_clicked_cb (ClutterClickAction *click_action,
|
||||
ClutterActor *actor,
|
||||
gpointer user_data)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
```
|
||||
|
||||
[gnome-coding-style]: https://developer.gnome.org/documentation/guidelines/programming/coding-style.html
|
504
NEWS
504
NEWS
@ -1,481 +1,3 @@
|
||||
41.0
|
||||
====
|
||||
* Avoid race in wl_seat capabilities [Olivier; !77]
|
||||
* Expose option groups/entries to introspection [Corentin; !1976]
|
||||
|
||||
Contributors:
|
||||
Olivier Fourdan, Corentin Noël
|
||||
|
||||
Translators:
|
||||
Daniel Șerbănescu [ro], Goran Vidović [hr], Luna Jernberg [sv],
|
||||
eshagh shahidani [fa], Gwan-gyeong Mun [ko], Emin Tufan Çetin [tr],
|
||||
Philipp Kiemle [de], Balázs Úr [hu], Piotr Drąg [pl], Nathan Follens [nl],
|
||||
Jordi Mas [ca], Ask Hjorth Larsen [da]
|
||||
|
||||
41.rc
|
||||
=====
|
||||
* Add clutter_stage_paint_to_content() [Ivan; !1899]
|
||||
* Add meta_cursor_tracker_get_scale() [Ivan; !1967]
|
||||
* wayland: Make each wl_output correspond to one monitor [Jonas; !1712]
|
||||
* Expose 'inactive-since' timestamp to uresourced [Nishal; !1960]
|
||||
* Pass dirty rects to secondary GPU [Piotr; !1879]
|
||||
* Support commiting preedit string on focus loss [Carlos; !1940]
|
||||
* Improve auto-rotation support [Marco; !1233]
|
||||
* Add meta_window_actor_paint_to_content() [Robert; !1893]
|
||||
* Fixed crashes [Jonas, Ray, Robert; !1947, !1979, !1965, !1958]
|
||||
* Misc. bug fixes and cleanups [Florian, Carlos, Robert, Daniel, Erico, Dor;
|
||||
!1957, !1924, !1970, !1971, !1972, !1973, !1974, !1977, !1978, !1975, !1886,
|
||||
!1983, !1990, !1980]
|
||||
|
||||
Contributors:
|
||||
Marco Trevisan (Treviño), Dor Askayo, Carlos Garnacho, Nishal Kulkarni,
|
||||
Piotr Lopatka, Robert Mader, Ivan Molodetskikh, Florian Müllner, Erico Nunes,
|
||||
Ray Strode, Daniel van Vugt, Jonas Ådahl
|
||||
|
||||
Translators:
|
||||
Asier Sarasua Garmendia [eu], Claude Paroz [fr], Jiri Grönroos [fi],
|
||||
Baurzhan Muftakhidinov [kk], Aurimas Černius [lt]
|
||||
|
||||
41.beta
|
||||
=======
|
||||
* Fix mouse position in remote desktop with fractional scaling [Pascal; !1867]
|
||||
* Manage idle monitors via MetaIdleManager [Jonas Å.; !1859]
|
||||
* Disable KMS modifiers on radeon driver [Carlos; !1872]
|
||||
* Fix fd leak [Carlos; !1870]
|
||||
* Fix adding virtual monitor to physical session [Jonas Å.; !1891]
|
||||
* Unbreak press-drag-release to pop up and select right click menus
|
||||
[Carlos; !1885]
|
||||
* Fix VKMS detection [Jonas Å.; !1892]
|
||||
* Fix swipe cancellation [JoseExposito; !1857]
|
||||
* Add ClutterTextureContent [Robert; !1888]
|
||||
* Fix mapping tablet to monitor [Christoph; !1887]
|
||||
* Fix area screencasts when window is unredirected [Michel; !1902]
|
||||
* Don't require a newly attached buffer to apply state [Christian, Jonas; !1795]
|
||||
* Close unused mode setting and rendering devices [Jonas Å.; !1828]
|
||||
* Only support super+scroll on wayland [Florian; !1922]
|
||||
* Implement the xdg-activation protocol [Carlos; !1845]
|
||||
* Reduce input latency by computing max render time heuristically [Ivan; !1762]
|
||||
* Apply dithering to dispatch time when needed [Daniel; !1826]
|
||||
* Introduce MetaContext [Jonas Å.; !1861]
|
||||
* x11: Compute monitor scale per output [Marco; !336]
|
||||
* Shrink and optimize the rounded-background-clip shader [Daniel; !1860]
|
||||
* remote-desktop: Handle non-responding selection owners [Pascal; !1874]
|
||||
* Improve sysprof support [Jonas Å.; !1700]
|
||||
* Allow clients to delegate titlebar gestures to the compositor [Florian; !1944]
|
||||
* Fix upside-down Xshape surface with EGLstream [Robert; !1937]
|
||||
* Fix 'kms-modifiers' experimental setting [Robert; !1953]
|
||||
* Make default focus window on each workspace appear focused [Alexander; !850]
|
||||
* Plugged memory leaks [Jonas Å.; !1869]
|
||||
* Fixed crashes crash [Daniel, Jonas Å., Florian; !1883, !1895,
|
||||
!1910, !1925, !1956]
|
||||
* Misc. bug fixes and cleanups [Jonas Å., Marco, Daniel, Florian, Georges,
|
||||
Zander, Carlos, Robert; !1833, !1863, !1876, !1873, !1884, !1890, !1900,
|
||||
!1912, !1916, !1911, !1920, !1865, !1927, !1923, !1929, !1100, !1932, !1931,
|
||||
!1862, !1933, !1930, !1935, !1936, !1878, !1938, !1942, !1951, !522, !1941]
|
||||
|
||||
Contributors:
|
||||
Marco Trevisan (Treviño), Zander Brown, Piotr Drąg, Michel Dänzer,
|
||||
Carlos Garnacho, JoseExposito, Robert Mader, Alexander Mikhaylenko,
|
||||
Ivan Molodetskikh, Florian Müllner, Georges Basile Stavracas Neto,
|
||||
Pascal Nowack, Christian Rauch, Christoph Trassl, Daniel van Vugt, Jonas Ådahl
|
||||
|
||||
Translators:
|
||||
Pawan Chitrakar [ne], Charles Monzat [fr], Dušan Kazik [sk],
|
||||
Quentin PAGÈS [oc], Alexey Rubtsov [ru], Alexander Shopov [bg],
|
||||
Florentina Mușat [ro], Chao-Hsiung Liao [zh_TW], Yuri Chornoivan [uk],
|
||||
Fran Dieguez [gl], Hugo Carvalho [pt], Rafael Fontenelle [pt_BR],
|
||||
Fabio Tomat [fur], Kukuh Syafaat [id], Yaron Shahrabani [he],
|
||||
Marek Černocký [cs], Matej Urbančič [sl], Boyuan Yang [zh_CN],
|
||||
Daniel Mustieles [es]
|
||||
|
||||
40.1
|
||||
====
|
||||
* Prevent clients from pasting old selection data [Carlos; !1772]
|
||||
* Fix forward_key IM functionality on wayland [Takao; !1802]
|
||||
* Ensure valid window texture size after viewport changes [Robert; !1799]
|
||||
* Only update cached paint volumes when necessary [Jonas D.; !1773, !1829]
|
||||
* Only disable KMS modifiers for drivers with known problems [Jonas Å; !1792]
|
||||
* Fix X11 client resize during moves [Olivier; !1777]
|
||||
* Fix performance drop during night light transition with Nvidia [Aaron; !1816]
|
||||
* kms: Don't add common modes that exceed the max bandwidth [Jonas Å.; !1834]
|
||||
* Create virtual input devices on demand [Jonas Å; !1800, !1858]
|
||||
* Fix wrong night light gamma when leaving power saving [Jonas Å.; !1835]
|
||||
* Fix picking edge case [Sebastian; !1842]
|
||||
* Properly tear down things when shutting down [Jonas Å.; !1822, !1856, !1853]
|
||||
* Fix monitor screencasting with fractional scaling [kirbykevinson; !1855]
|
||||
* Fixed crash [Carlos; !1849]
|
||||
* Plugged memory leak [Carlos; !1839]
|
||||
* Misc. bug fixes and cleanups [Carlos, Daniel, Jonas D., Jonas Å., Robert,
|
||||
Aleksandr, Florian, Michel, Sebastian, Olivier; !1785, !1798, !1784,
|
||||
!1791, !1801, !1807, !1786, !1793, !1804, !1820, !1824, !1819, !1803,
|
||||
!1821, !1806, !1814, !1831, !1832, !1836, !1843, !1740, !1841, !1827,
|
||||
!1844, !1852, !1850, !1851]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Michel Dänzer, Jonas Dreßler, Olivier Fourdan, Takao Fujiwara,
|
||||
Carlos Garnacho, Sebastian Keller, kirbykevinson, Robert Mader,
|
||||
Aleksandr Mezin, Florian Müllner, Aaron Plattner, Daniel van Vugt
|
||||
|
||||
Translators:
|
||||
Bruce Cowan [en_GB], Ngọc Quân Trần [vi], Marek Černocký [cs],
|
||||
Dz Chen [zh_CN], Yosef Or Boczko [he], Nathan Follens [nl],
|
||||
Yuri Chornoivan [uk], Jordi Mas [ca], Piotr Drąg [pl], Tim Sabsch [de],
|
||||
Luna Jernberg [sv], Hugo Carvalho [pt], Rafael Fontenelle [pt_BR],
|
||||
Asier Sarasua Garmendia [eu], Quentin PAGÈS [oc], Matej Urbančič [sl]
|
||||
|
||||
40.0
|
||||
====
|
||||
* xwayland: Check permissions on /tmp/.X11-unix [Olivier; !1787]
|
||||
|
||||
Contributors:
|
||||
Olivier Fourdan
|
||||
|
||||
Translators:
|
||||
Hugo Carvalho [pt], Tim Sabsch [de], Daniel Mustieles [es],
|
||||
Matej Urbančič [sl], Марко Костић [sr], Fran Dieguez [gl]
|
||||
|
||||
40.rc
|
||||
=====
|
||||
* Fix keyboard input from remote desktop in Xorg session [Pascal; !1732]
|
||||
* Fix restoring focus to windows using globally active input [Olivier; !1716]
|
||||
* Expose unaccalerated touchpad gesture deltas [Alexander; !1353]
|
||||
* Avoid relayout on text attribute changes when possible [Jonas D.; !1750]
|
||||
* Add remote desktop caps- and num-lock state properties [Jonas Å.; !1739]
|
||||
* Improve refresh rate calculation [Akihiko; !1737]
|
||||
* Implement presentation-time protocol [Ivan; !1484]
|
||||
* Disable double-buffered shadow buffering [Jonas Å.; !1724]
|
||||
* Fix missing cursor on tablet devices [Jonas D.; !1758]
|
||||
* Fix frame timings causing X11 clients to get stuck [Jonas Å.; !1754]
|
||||
* Fix applying input settings on X11 [Marco, Suryashankar; !1769, !1767]
|
||||
* Add headless native backend [Jonas Å.; !1698]
|
||||
* Fix high latency and stalls with proprietary nvidia driver [Daniel; !1726]
|
||||
* Fix maximized windows not reacting to strut changes [Aleksandr; !1755]
|
||||
* Only start XWayland on demand when running under systemd [Benjamin; !1771]
|
||||
* Sync LEDs when a new input device is added [Olivier; !1662]
|
||||
* Fix order in which subsurface placement operations are handled [Robert; !1768]
|
||||
* Fixed crashes [Jonas Å., Sebastian; !1745, !1747, !1759, !1748, !1776, !1775]
|
||||
* Plugged leaks [Philip, Sebastian; !1738, !1728]
|
||||
* Misc. bug fixes and cleanups [Jonas Å., Jonas D., Ivan, Florian, Marco,
|
||||
Robert; !1688, !1744, !1736, !1749, !1752, !1753, !427, !1757, !1751, !1760,
|
||||
!1765, !1770, !1763, !1774, !1780, !1779, !1783]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Benjamin Berg, Suryashankar Das, Jonas Dreßler, Olivier Fourdan,
|
||||
Sebastian Keller, Robert Mader, Aleksandr Mezin, Alexander Mikhaylenko,
|
||||
Ivan Molodetskikh, Florian Müllner, Pascal Nowack, Akihiko Odaki,
|
||||
Marco Trevisan (Treviño), Daniel van Vugt, Philip Withnall
|
||||
|
||||
Translators:
|
||||
Fran Dieguez [gl], Asier Sarasua Garmendia [eu], Claude Paroz [fr],
|
||||
Piotr Drąg [pl], Hugo Carvalho [pt], Jordi Mas [ca], Fabio Tomat [fur],
|
||||
Yuri Chornoivan [uk], Enrico Nicoletto [pt_BR], Emin Tufan Çetin [tr],
|
||||
Daniel Șerbănescu [ro], Marek Černocký [cs], Balázs Úr [hu],
|
||||
Aurimas Černius [lt], Kukuh Syafaat [id], A S Alam [pa], Anders Jonsson [sv],
|
||||
Milo Casagrande [it], Gwan-gyeong Mun [ko]
|
||||
|
||||
40.beta
|
||||
=======
|
||||
* Consider clients without mapped windows for xwayland auto-shutdown
|
||||
[Olivier; !1671]
|
||||
* Let compositor to handle super+scroll events [Florian; !1674, !1695]
|
||||
* Default to starting Xwayland on demand [Olivier; !1673]
|
||||
* xwayland: Restore abstract socket support [James, Olivier; !1669]
|
||||
* Add support for atomic mode setting [Jonas Å.; !1488]
|
||||
* Fix clip region glitches when using fractional scaling [Daniel; !1554]
|
||||
* Default to horizontal workspace layout [Georges, Florian; !1684, !1706]
|
||||
* Do not ping unmanaging windows [Florian; gnome-shell#2467]
|
||||
* Handle monitor changes during screencasts [Jonas Å.; !1691]
|
||||
* Fix unexpected jumps after restoring misbehaving clients [Jonas Å.; !1445]
|
||||
* Fix newly opened X11 windows being invisible in overview [Olivier; !1678]
|
||||
* Fix viewport of offscreen effects [Daniel; !1053]
|
||||
* Fix drag cancel animation when using geometry scaling [Robert; !1683]
|
||||
* Improve touch-mode heuristics [Carlos; !1710]
|
||||
* Integrate clipboard with remote desktop sessions [Jonas Å.; !1552]
|
||||
* Fix stuck icon in DND operation between X11 and wayland [Carlos; !1720]
|
||||
* Automatically synchronize pointer position after modal grabs [Carlos; !1659]
|
||||
* Reimplement support for CLUTTER_SHOW_FPS [Daniel; !154]
|
||||
* Only pick on events that may move the pointer [Jonas D.; !1729, !1733]
|
||||
* Emit discrete scroll events for accumulated smooth events in virtual
|
||||
X11 devices [Pascal; !1727]
|
||||
* Add support for rounded clipping when drawing background [Jonas D.; !1717]
|
||||
* Plugged memory leaks [Sebastian; !1307, !1699]
|
||||
* Fixed crashes [Carlos, Thomas, Jonas Å., Olivier; !1677, !1685, !1692,
|
||||
!1719, !1718, !1735]
|
||||
* Misc. bug fixes and cleanups [Jonas Å., Carlos, Olivier, Sebastian, Björn,
|
||||
Jonas D., Ivan, Georges, Dor, Michel, Robert; !1670, !1679, !1680, !1682,
|
||||
!1681, !1661, !1689, !1690, !1693, !1514, !1696, !1697, !1708, !1709, !1707,
|
||||
!1701, !1702, !1715, !1725, !1734, !1512]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Dor Askayo, Björn Daase, Michel Dänzer, Jonas Dreßler,
|
||||
Olivier Fourdan, Carlos Garnacho, James Henstridge, Sebastian Keller,
|
||||
Robert Mader, Ivan Molodetskikh, Thomas Mühlbacher, Florian Müllner,
|
||||
Georges Basile Stavracas Neto, Pascal Nowack, Daniel van Vugt
|
||||
|
||||
Translators:
|
||||
Марко Костић [sr], Jordi Mas [ca], Yuri Chornoivan [uk],
|
||||
Daniel Șerbănescu [ro], Hugo Carvalho [pt], Fran Dieguez [gl],
|
||||
Matej Urbančič [sl], Marek Černocký [cs], Rafael Fontenelle [pt_BR],
|
||||
Philipp Kiemle [de], A S Alam [pa], Balázs Úr [hu], Anders Jonsson [sv],
|
||||
Daniel Mustieles [es], Emin Tufan Çetin [tr], Kukuh Syafaat [id],
|
||||
Aurimas Černius [lt]
|
||||
|
||||
40.alpha.1.1
|
||||
============
|
||||
* Adapt to settings moving to gsettings-desktop-schemas [Carlos; !1416]
|
||||
* Misc. bug fixes and cleanups [Georges; !1667]
|
||||
|
||||
Contributors:
|
||||
Carlos Garnacho, Georges Basile Stavracas Neto
|
||||
|
||||
40.alpha.1
|
||||
==========
|
||||
* Base ClutterEffects on ClutterPaintNodes [Georges; !1340, !1355]
|
||||
* xwayland: Set xrandr primary output [Aleksandr; !1558]
|
||||
* Add paint node based blur support [Georges; !1627, !1646]
|
||||
* Disable CRTCs if there is no monitor [Kai-Heng; !1561]
|
||||
* Fix updates of mipmapped animated backgrounds [Daniel; !1664]
|
||||
* Allow remote desktop clients to specify scroll source [Pascal; !1636]
|
||||
* Support the color transform matrix RandR property on X11 [Aaron; !1048]
|
||||
* Plugged memory leaks [Jonas D.; !1632]
|
||||
* Fixed crashes [Jonas Å., Olivier, Carlos; !1557, !1648, !1643, !1654, !1663]
|
||||
* Misc. bug fixes and cleanups [Olivier, Niels, Carlos, Jonas Å., Florian,
|
||||
Jonas D., Daniel, Georges, Michel, Sebastian, Marc-Antoine; !1621, !1622,
|
||||
!1624, !1623, !1625, !1626, !1630, !1631, !1576, !1635, !1640, !1642,
|
||||
!1639, !1644, !1637, !1615, !1647, !1633, !1634, !1651, !1652, !1657,
|
||||
!1660, !1658, !1665, !1649, !1668, !1655]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Michel Dänzer, Jonas Dreßler, Kai-Heng Feng, Olivier Fourdan,
|
||||
Carlos Garnacho, Niels De Graef, Sebastian Keller, Aleksandr Mezin,
|
||||
Florian Müllner, Georges Basile Stavracas Neto, Pascal Nowack,
|
||||
Marc-Antoine Perennou, Aaron Plattner, Daniel van Vugt
|
||||
|
||||
Translators:
|
||||
Kjartan Maraas [nb], Juliano de Souza Camargo [pt], Florentina Mușat [ro],
|
||||
Daniel Mustieles [es], Jordi Mas i Hernandez [ca], Fabio Tomat [fur],
|
||||
Philipp Kiemle [de], Asier Sarasua Garmendia [eu], Aurimas Černius [lt],
|
||||
Fran Dieguez [gl], Hugo Carvalho [pt], Matej Urbančič [sl]
|
||||
|
||||
40.alpha
|
||||
========
|
||||
* Replace CoglMatrix with graphene_matrix [Georges; !1439]
|
||||
* Allow to specify debug topics in MUTTER_DEBUG [Jonas Å.; !1465]
|
||||
* Fix unwanted position changes on window resize
|
||||
[Jonas Å., Olivier, Robert; !1477, !1495]
|
||||
* Do not disable the X Security extension by default [Olivier; !1485]
|
||||
* Fix _NET_WM_FRAME_DRAWN timestamps [Jonas Å.; !1494]
|
||||
* Fix tiling to the correct monitor [Florian; #1389]
|
||||
* Only snap to window edges when CTRL is pressed [Florian; #679609]
|
||||
* Add support for scroll button locking [Peter; !1432]
|
||||
* Clip Frustra [Georges; !1489]
|
||||
* Improve tablet-mode-switch support [Hans; !1506]
|
||||
* Fix missed redraws of newly-mapped actors [Jonas D.; !1366, #1494]
|
||||
* Gracefully handle Xwayland crashes [Carlos; !1447]
|
||||
* wayland: Provide previous window dimensions on restore [Christian; !801]
|
||||
* Remove the ClutterActor::paint signal [Jonas; !1522]
|
||||
* Fix background artifacts in magnifier [Daniel; #1480]
|
||||
* Use raycasting for picking [Georges; !1509]
|
||||
* Fix monitor tiling support on X11 [Jonas Å.; #1524]
|
||||
* Fix xwayland grabs for override-redirect windows [Olivier; !1254]
|
||||
* Fix device configuration not being picked up on X11 [Carlos; !1553]
|
||||
* Support tagging devices as primary GPU via udev [Jonas Å.; !1562]
|
||||
* Fix size hints with CSD [Olivier; !1594]
|
||||
* Fix unresponsive input after screen blank [Simon; !1601]
|
||||
* Cull actors when picking [Georges; !1520]
|
||||
* Handle input in a thread [Carlos; !1403]
|
||||
* Improve freezes when switching workspace [Jonas Å.; !1616]
|
||||
* Plugged memory leaks [Ray; !1225]
|
||||
* Fixed crashes [Christian, Olivier, Daniel, Robert, Jonas Å., Florian Z.,
|
||||
Simon, Carlos; #1481, !1529, !1519, !1534, #1521, !1563, !1604, !1605,
|
||||
!1607, !1612]
|
||||
* Misc. bug fixes and cleanups [Florian, Carlos, Olivier, Georges, Björn,
|
||||
Jonas Å., Julius, Corentin, Bastien, Robert, Daniel, Niels, Jonas D., Uday,
|
||||
Ian, Jordan, Piotr; !1473, !1472, !1438, #1449, !1475, !1474, !1481, !1466,
|
||||
!1483, !1427, !1413, !1103, !1467, !1339, !1297, #1384, !1491, !528, !1496,
|
||||
!1510, !1507, !1387, !1498, !1515, !1516, !1517, !1486, !1524, !1527, !1528,
|
||||
!1531, !1532, !1521, !1535, #1490, !1545, !1555, !1564, !1549, !1567, !1565,
|
||||
!1572, !1569, !1573, !1566, !1525, !1468, !1578, !1583, !1584, !1585, !1571,
|
||||
!1327, !1586, !1590, !1588, !1050, !1596, !1592, !1587, !1599, !1577, !1511,
|
||||
!1591, !1603, !1611, !1593, !1617, !1619]
|
||||
|
||||
Contributors:
|
||||
Björn Daase, Jonas Dreßler, Piotr Drąg, Olivier Fourdan, Carlos Garnacho,
|
||||
Hans de Goede, Niels De Graef, Peter Hutterer, Julius Lehmann, Robert Mader,
|
||||
Simon McVittie, Florian Müllner, Georges Basile Stavracas Neto,
|
||||
Bastien Nocera, Corentin Noël, Jordan Petridis, Uday Kiran Pichika,
|
||||
Christian Rauch, Ian Douglas Scott, Ray Strode, Daniel van Vugt,
|
||||
Florian Zwoch, Jonas Ådahl
|
||||
|
||||
Translators:
|
||||
Juliano de Souza Camargo [pt], Ask Hjorth Larsen [da], Yuri Chornoivan [uk]
|
||||
|
||||
3.38.1
|
||||
======
|
||||
* Fix Night Light updates after DPMS [Jonas, Benjamin; #1392]
|
||||
* Fix button scrolling on X11 [Peter; !1431]
|
||||
* Always use correct font-dpi setting on X11 [Marco; !1444]
|
||||
* Improve handling of scanout failures [Jonas; #1410]
|
||||
* Fix middle/right button mixup in scroll button assignment [Peter; !1433]
|
||||
* Fix resizing of attached modal dialogs on wayland [Jonas; !1446]
|
||||
* Enable KMS modifiers on devices that need them [Karol; !1443]
|
||||
* Fix IM handling on X11 [Carlos; #1413]
|
||||
* Fix glitches in "undefined" screencast areas [Jonas; !1459]
|
||||
* Fix visual glitches on background with fractional scaling [Daniel; !1464]
|
||||
* Fix using correct refresh rate [Jonas; #1430]
|
||||
* Misc. bug fixes and cleanups [Daniel, Carlos, Robert, Simon, Sergio; !1362,
|
||||
!1448, !1452, !1273, !1454, !1429, !1460, !1458, !1463, !1462]
|
||||
* Plugged memory leaks [Ray; !1449, !1451]
|
||||
|
||||
Contributors:
|
||||
Marco Trevisan (Treviño), Benjamin Berg, Sergio Costas, Carlos Garnacho,
|
||||
Karol Herbst, Peter Hutterer, Robert Mader, Simon McVittie, Ray Strode,
|
||||
Daniel van Vugt, Jonas Ådahl
|
||||
|
||||
Translators:
|
||||
Juliano de Souza Camargo [pt], Rafael Fontenelle [pt_BR],
|
||||
Yosef Or Boczko [he], Jordi Mas [ca]
|
||||
|
||||
3.38.0
|
||||
======
|
||||
* screencast: Only use DMA buffers for i915 [Jonas; !1442]
|
||||
* Fixed crashes [Jonas, Simon; !1430, #1414]
|
||||
|
||||
Contributors:
|
||||
Simon McVittie, Jonas Ådahl
|
||||
|
||||
Translators:
|
||||
Anders Jonsson [sv], Gil Forcada [ca], Balázs Meskó [hu], Tim Sabsch [de],
|
||||
Milo Casagrande [it], Bruce Cowan [en_GB], Rūdolfs Mazurs [lv]
|
||||
|
||||
3.37.92
|
||||
=======
|
||||
* Fix stale cursor positions in remote desktop sessions [Georges; !1417]
|
||||
* xwayland: Add a setting to disable selected X extensions [Olivier; !1405]
|
||||
* Fix screencasting when using QXL [Jonas Å., Grey; !1318]
|
||||
* Cull actors that don't intersect with the redraw clip [Daniel; !1359]
|
||||
* Optimize painting of backgrounds when culling is unavailable [Daniel; !1363]
|
||||
* Improve support for Hangul input method [Carlos; !1286]
|
||||
* Support debug paint overlay for opaque regions [Robert; !1372]
|
||||
* Fix launching flatpak applications when autostarting Xwayland [Carlos; !1424]
|
||||
* Add support for capture scanouts in screencasts [Georges; !1421]
|
||||
* Allow integrated tablet devices to cycle outputs [Carlos; !1201]
|
||||
* Improve mapping input devices to the most relevant output [Carlos; !1202]
|
||||
* Only enable auto-rotation in touch mode [Carlos; !1311]
|
||||
* Fixed crashes [Pascal, Robert, Carlos, Benjamin, Marco; !1414, !1409, !1408,
|
||||
!1415, #1395, !1392, !1371, #1345]
|
||||
* Misc. bug fixes and cleanups [Björn, Jonas D., Florian; !1410, !1358, !1425]
|
||||
|
||||
Contributors:
|
||||
Marco Trevisan (Treviño), Benjamin Berg, Grey Christoforo, Björn Daase,
|
||||
Jonas Dreßler, Olivier Fourdan, Carlos Garnacho, Robert Mader,
|
||||
Florian Müllner, Georges Basile Stavracas Neto, Pascal Nowack,
|
||||
Daniel van Vugt, Jonas Ådahl
|
||||
|
||||
Translators:
|
||||
Marek Černocký [cs], Aurimas Černius [lt], Asier Sarasua Garmendia [eu],
|
||||
Gwan-gyeong Mun [ko], Yuri Chornoivan [uk], Boyuan Yang [zh_CN],
|
||||
Kukuh Syafaat [id], Piotr Drąg [pl], Rafael Fontenelle [pt_BR],
|
||||
Марко Костић [sr], Matej Urbančič [sl], Fabio Tomat [fur],
|
||||
Daniel Mustieles [es], Fran Dieguez [gl], Goran Vidović [hr],
|
||||
Claude Paroz [fr], Andre Klapper [or, ug, te], Emin Tufan Çetin [tr]
|
||||
|
||||
3.37.91
|
||||
=======
|
||||
* Fix initial state of display mode OSD [Jian-Hong; #1362]
|
||||
* Fixed crashes [Jonas Å., Robert; !1407, !1411]
|
||||
* Misc. bug fixes and cleanups [Jonas Å., Christian; !1404, !1364, #1331]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Robert Mader, Jian-Hong Pan, Christian Rauch
|
||||
|
||||
Translators:
|
||||
Fran Dieguez [gl], Daniel Mustieles [es], Florentina Mușat [ro],
|
||||
Kukuh Syafaat [id], Piotr Drąg [pl], Emin Tufan Çetin [tr], Марко Костић [sr],
|
||||
Akarshan Biswas [bn_IN], Matej Urbančič [sl], Boyuan Yang [zh_CN],
|
||||
Goran Vidović [hr], Rafael Fontenelle [pt_BR]
|
||||
|
||||
3.37.90
|
||||
=======
|
||||
* Fix using NEAREST filter for backgrounds on scaled monitors [Daniel V.; !1346]
|
||||
* Screencast fixes and improvements [Jonas; !1361, !1377, !1391]
|
||||
* Support tap-button-map and tap-drag-lock touchpad settings [Giusy; !1319]
|
||||
* Fix wine copy & paste [Sebastian; !1369]
|
||||
* Fix shadows of server-side decorated XWayland windows [Olivier; #1358]
|
||||
* Replace some loaded terms with more descriptive ones [Olivier; !1396]
|
||||
* Add API to launch trusted wayland clients [Sergio; #741]
|
||||
* Skip displays with 'non-desktop' property set [Philipp; !1393]
|
||||
* Invalidate offscreen effect cache on video memory purge [Daniel V.; !1374]
|
||||
* Add wl_shm support for 10 bpc and 16 bpc half float formats [Jonas; !804]
|
||||
* Fixed crashes [Jonas, Erik, Martin; !1365, !1375, #1343]
|
||||
* Misc. bug fixes and cleanups [Daniel V., Carlos, Olivier, Christian,
|
||||
Daniel * G., Jonas, Florian; !1370, !1376, !1385, !1352, !1386, !1390,
|
||||
!1388, !1397, !1398, !1401]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Sergio Costas, Olivier Fourdan, Carlos Garnacho,
|
||||
Christian Hergert, Sebastian Keller, Erik Kurzinger, Giusy Margarita,
|
||||
Daniel García Moreno, Florian Müllner, Daniel van Vugt, Martin Whitaker,
|
||||
Philipp Zabel
|
||||
|
||||
Translators:
|
||||
Fabio Tomat [fur], Rafael Fontenelle [pt_BR], Jordi Mas [ca],
|
||||
Yuri Chornoivan [uk], Alexandre Franke [fr]
|
||||
|
||||
3.37.3
|
||||
======
|
||||
* Support custom keyboard layouts in $XDG_CONFIG_HOME/xkb [Peter; !936]
|
||||
* Optimize resource scale computation [Jonas D.; !1196, !1276, !1343]
|
||||
* Allow animating ClutterActor's content property [Georges; !1301]
|
||||
* Implement backgrounds as ClutterContent [Georges; !1302]
|
||||
* Add ClutterAlignContraint:pivot-point property [Jonas D.; !737]
|
||||
* Fix crash on area screenshots with fractional scaling [Sebastian; !1320]
|
||||
* Do not paint textures of fully obscured windows [Robert; !1326]
|
||||
* Use a more appropriate combine function on opaque areas [Daniel; !1331]
|
||||
* Fix remote desktop being broken without screencast session [Olivier; #1307]
|
||||
* Remove more long-deprecated Clutter APIs [Adam, Georges; !1194, !1332]
|
||||
* Drive each monitor by its own frame clock [Jonas Å.; !1285]
|
||||
* Fix copy/paste failures on X11 [Carlos; !1350]
|
||||
* Mipmap background texture rendering [Daniel; !1347]
|
||||
* Plugged memory leaks [Sebastian, Jonas D.; !1293, !1281, !1304]
|
||||
* Misc. bug fixes and cleanups [Jonas Å., Jonas D., Daniel, Corentin, Carlos,
|
||||
Sebastian, Michel, Robert, Florian; !1288, !1289, !1291, !1296, !1292, !1298,
|
||||
!1300, !1303, !1290, !1287, !1306, !1305, !1308, !1313, !1250, !1314, !1267,
|
||||
!1275, !1317, !1270, !1322, !1181, !1282, !1325, !1323, !1240, !1295, !1329,
|
||||
!1333, !1334, !1336, !1341, #1312, !1345, !1349, !1356, #873, !1310, !1357]
|
||||
|
||||
Contributors:
|
||||
Jonas Dreßler, Michel Dänzer, Olivier Fourdan, Carlos Garnacho,
|
||||
Peter Hutterer, Adam Jackson, Sebastian Keller, Robert Mader, Florian Müllner,
|
||||
Georges Basile Stavracas Neto, Corentin Noël, Daniel van Vugt, Jonas Ådahl
|
||||
|
||||
3.37.2
|
||||
======
|
||||
* Fix move-to-center keybinding with multiple monitors [Sergey; #1073]
|
||||
* Fix stuck buttons when a virtual device is destroyed [Carlos; !1239]
|
||||
* Use workarea when centering new windows [Akatsuki; #964]
|
||||
* Limit mipmap levels when rendering background [Daniel; !1003]
|
||||
* Broadcast clipboard/primary offers [Carlos; !1253]
|
||||
* Support primary-selection protocol from wayland-protocols [Carlos; !1255]
|
||||
* Fix monitor screen cast on X11 [Jonas Å.; !1251]
|
||||
* Support a "blank" cursor type [Florian; !1244]
|
||||
* Improve stage view damage tracking [Jonas Å.; !1237]
|
||||
* Implement touch-mode detecation for the X11 backend [Carlos; !1278]
|
||||
* Drop external keyboard detection from touch-mode heuristics [Carlos; !1277]
|
||||
* Optimize actor allocations [Jonas D.; !1247]
|
||||
* Fixed crashes [Daniel, Carlos, Jonas Å., Jonas D.; !1256, !1258, !1217, !1280]
|
||||
* Misc. bug fixes and cleanups [Christian, Jonas D., Olivier, Ting-Wei,
|
||||
Jonas Å., Marco, Corentin, Daniel, Robert, Niels, Florian, Simon; !1231,
|
||||
!1228, !1238, !1229, !1192, !1236, !1171, !1134, #1126, !1234, !1230, !1210,
|
||||
!1242, !1243, !1252, !1113, !1232, !1259, !1245, !1265, !1180, !1261, !788,
|
||||
!1264, !1235, !1218, !1150, !1274, !1271, !1279, !1283, !1272]
|
||||
|
||||
Contributors:
|
||||
Marco Trevisan (Treviño), Akatsuki, Jonas Dreßler, Olivier Fourdan,
|
||||
Carlos Garnacho, Niels De Graef, Ting-Wei Lan, Robert Mader, Simon McVittie,
|
||||
Florian Müllner, Corentin Noël, Christian Rauch, Daniel van Vugt,
|
||||
Sergey Zigachev, Jonas Ådahl
|
||||
|
||||
3.37.1
|
||||
======
|
||||
* Fix screencasting non-maximized windows [Jonas Å.; !1174]
|
||||
@ -954,7 +476,7 @@ Contributors:
|
||||
3.31.92
|
||||
=======
|
||||
* Fix flicker of apps that use multiple SHM buffers [Jonas Å.; #199]
|
||||
* Don't disable page flips after temporary failures [Jonas Å.; #460]
|
||||
* Don't disable page flips after temporary failues [Jonas Å.; #460]
|
||||
* Improve redraw performance [Carlos; !196]
|
||||
* Add cursor-mode support to window screencasting [Jonas Å.; !413]
|
||||
* Add back support for system-wide monitor configurations [Jonas Å.; !253]
|
||||
@ -1366,7 +888,7 @@ Translations:
|
||||
=======
|
||||
* Reduce memory use of suspended instances [Jonas; #786299]
|
||||
* Make supported scales determination saner [Rui; #786474]
|
||||
* Fix crash on inhibit-shortcuts dialog response [Jonas; #786385]
|
||||
* Fix crash on inhibit-shortcuts dialog reponse [Jonas; #786385]
|
||||
* Support libinput's tag-and-drag setting [freeroot; #775755]
|
||||
* Avoid overlapping keybindings with multiple layouts [Jonas; #786408]
|
||||
* Fix non-transformed cursor on rotated monitors [Jonas; #786023]
|
||||
@ -1685,7 +1207,7 @@ Translations:
|
||||
* Consider XDG_SESSION_TYPE when determining session type [Jouke; #759388]
|
||||
* Re-add support for edge scrolling on some touchpads [Bastien; #768245]
|
||||
* Support mouse and trackball acceleration profile [Jonas; #769179]
|
||||
* Draw monitor content to individual framebuffer [Jonas; #768976]
|
||||
* Draw monitor contentn to individual framebuffer [Jonas; #768976]
|
||||
* Support virtual input devices [Jonas, Carlos; #765009]
|
||||
* Set correct output scale on hotplug [Jonas; #769505]
|
||||
* Misc. bug fixes and cleanups [Florian, Jonas, Thomas, Bastien, Carlos;
|
||||
@ -2510,7 +2032,7 @@ Translations:
|
||||
* Ignore skip-taskbar hints on parentless dialogs [Giovanni; #673399]
|
||||
* Don't save pixbuf data in user data [Tim; #706777]
|
||||
* Don't queue redraws for obscured regions [Adel; #703332]
|
||||
* Support the opaque region hints for wayland clients [Jasper; #707019]
|
||||
* Suppor the opaque region hints for wayland clients [Jasper; #707019]
|
||||
* Turn blending off when drawing entirely opaque regions [Jasper; #707019]
|
||||
* Check event timestamps before reconfiguring [Giovanni; #706735]
|
||||
* Merge the DBus API for display configuration in the wayland branch [Giovanni]
|
||||
@ -2995,7 +2517,7 @@ Translations:
|
||||
======
|
||||
* Automaximize large windows on map [Adel; #671677]
|
||||
* When unmaximizing windows, make sure the unminimized size
|
||||
is significantly less than the maximized size [Adel; #671677]
|
||||
is signficantly less than the maximized size [Adel; #671677]
|
||||
* Don't offer maximize option for windows larger than the screen
|
||||
[Jasper; #643606]
|
||||
* Always focus the window immediately underneath without restacking
|
||||
@ -3095,7 +2617,7 @@ Translations:
|
||||
* Move from GConf to GSettings for preferences [Florian; #635378]
|
||||
* Add meta_display_add_keybinding()/meta_display_remove_keybinding()
|
||||
to allow creating new keybindings at runtime [Florian; #663428]
|
||||
* Add support for new _NET_WM_STATE_FOCUSED atom in _NET_WM_STATE
|
||||
* Add suport for new _NET_WM_STATE_FOCUSED atom in _NET_WM_STATE
|
||||
to allow applications to draw unfocused windows differently
|
||||
[Rui; #661427]
|
||||
* Add meta_window_move_resize_frame() to allow specifying the
|
||||
@ -3207,7 +2729,7 @@ Contributors:
|
||||
for easy resizing with thin borders. (New draggable_border_width GConf key
|
||||
controls the total width of visible and invisible borders.)
|
||||
[Jasper; #644930]
|
||||
* Draw rounded window corners with antialiasing [Jasper; #628195]
|
||||
* Draw rounded window corners with antialising [Jasper; #628195]
|
||||
* Unredirect override-redirect fullscreen windows, such as full-screen
|
||||
3D games to avoid any performance impact [Adel; #597014]
|
||||
* Add :resizable and :above properties to MetaWindow. [Tim; #653858]
|
||||
@ -3300,7 +2822,7 @@ Translations:
|
||||
3.0.2.1
|
||||
=======
|
||||
* When saving the session, use the "program name" rather than
|
||||
hardcoding mutter, fixing session saving for gnome-shell [Matthias]
|
||||
harcoding mutter, fixing session saving for gnome-shell [Matthias]
|
||||
https://bugzilla.gnome.org/show_bug.cgi?id=648828
|
||||
|
||||
Contributors:
|
||||
@ -3618,7 +3140,7 @@ Bugs fixed:
|
||||
634779 MetaWindowGroup: further optimize paints by using current scissor
|
||||
634833 Draw the root window background
|
||||
592382 improve shadow effect
|
||||
628199 Add antialiasing to arc and line drawing operations
|
||||
628199 Add antialising to arc and line drawing operations
|
||||
633002 meta-actor-window: Use G_UNLIKELY for TFP check
|
||||
634771 MetaStackTracker: Avoid queueing resync for obvious no-ops
|
||||
635421 Fix crash in check_needs_shadow
|
||||
@ -3815,7 +3337,7 @@ Fixed Bugs:
|
||||
- Allow a theme to turn on title ellipsization
|
||||
* Performance enhancements:
|
||||
- Stream raw damage updates to ClutterX11TexturePixmap
|
||||
to enable partial stage updates when windows change [Robert]
|
||||
to enable partial stage updates when windos change [Robert]
|
||||
- Don't trap XErrors in meta_compositor_process_event [Adel]
|
||||
* Add meta_prefs_override_preference_location(); this allows
|
||||
a plugin like GNOME Shell to redirect preferences to a
|
||||
@ -3860,7 +3382,7 @@ Fixed Bugs:
|
||||
613136 - remove over-restrictive assert from meta_prefs_get_workspace_name()
|
||||
613398 - Don't trap XErrors in meta_compositor_process_event
|
||||
615586 - Allow redirecting preferences to a different GConf key
|
||||
615672 - can't compile mutter error: dereferencing pointer ‘p’ does break
|
||||
615672 - cant' compile mutter error: dereferencing pointer ‘p’ does break
|
||||
strict-aliasing rules
|
||||
616050 - alt-tab infrastructure patches
|
||||
616274 - mutter from git fails with gcc 4.5 (on new warning)
|
||||
@ -4806,7 +4328,7 @@ Arthur Taylor, Elijah Newren, Josselin Mouette, Havoc Pennington,
|
||||
Benjamin Berg, and Carlo Wood for improvements in this release.
|
||||
|
||||
- new icon for the force-quit dialog (Jaap) [#396655]
|
||||
- add configurable mouse click action abilities, and clean up lots of
|
||||
- add configureable mouse click action abilities, and clean up lots of
|
||||
related code (Linus) [#408899, #408902, others]
|
||||
- add schemeas for middle and right click titlebar actions (Charlie)
|
||||
[#408903]
|
||||
@ -5360,7 +4882,7 @@ this release.
|
||||
running with --disable-gconf. Make --disable-gconf actually work.
|
||||
(Elijah) [#326661]
|
||||
- fix some reading-from-free'd-data errors (Søren) [#327575]
|
||||
- fix an uninitialized value problem when in raise-on-click mode
|
||||
- fix an unitialized value problem when in raise-on-click mode
|
||||
(Søren) [#327572]
|
||||
- avoid flashing original-sized window when closing a maximized
|
||||
window (Elijah) [#317254]
|
||||
|
31
README.md
31
README.md
@ -26,34 +26,15 @@ debugging purposes.
|
||||
|
||||
To contribute, open merge requests at https://gitlab.gnome.org/GNOME/mutter.
|
||||
|
||||
It can be useful to look at the documentation available at the
|
||||
[Wiki](https://gitlab.gnome.org/GNOME/mutter/-/wikis/home).
|
||||
|
||||
## Coding style and conventions
|
||||
|
||||
See [HACKING.md](./HACKING.md).
|
||||
|
||||
## Git messages
|
||||
The coding style used is primarily the GNU flavor of the [GNOME coding
|
||||
style](https://developer.gnome.org/programming-guidelines/stable/c-coding-style.html.en)
|
||||
with some minor additions such as preferring `stdint.h` types over GLib
|
||||
fundamental types, and a soft 80 character line limit. However, in general,
|
||||
look at the file you're editing for inspiration.
|
||||
|
||||
Commit messages should follow the [GNOME commit message
|
||||
guidelines](https://wiki.gnome.org/Git/CommitMessages). We require an URL
|
||||
to either an issue or a merge request in each commit. Try to always prefix
|
||||
commit subjects with a relevant topic, such as `compositor:` or
|
||||
`clutter/actor:`, and it's always better to write too much in the commit
|
||||
message body than too little.
|
||||
|
||||
## Default branch
|
||||
|
||||
The default development branch is `main`. If you still have a local
|
||||
checkout under the old name, use:
|
||||
```sh
|
||||
git checkout master
|
||||
git branch -m master main
|
||||
git fetch
|
||||
git branch --unset-upstream
|
||||
git branch -u origin/main
|
||||
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
|
||||
```
|
||||
to either an issue or a merge request in each commit.
|
||||
|
||||
## License
|
||||
|
||||
|
138
check-style.py
138
check-style.py
@ -1,138 +0,0 @@
|
||||
#!/bin/env python3
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
# Path relative to this script
|
||||
uncrustify_cfg = 'tools/uncrustify.cfg'
|
||||
|
||||
def run_diff(sha):
|
||||
proc = subprocess.Popen(["git", "diff", "-U0", "--function-context", sha, "HEAD"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
files = proc.stdout.read().strip().decode('utf-8')
|
||||
return files.split('\n')
|
||||
|
||||
def find_chunks(diff):
|
||||
file_entry_re = re.compile('^\+\+\+ b/(.*)$')
|
||||
diff_chunk_re = re.compile('^@@ -\d+,\d+ \+(\d+),(\d+)')
|
||||
file = None
|
||||
chunks = []
|
||||
|
||||
for line in diff:
|
||||
match = file_entry_re.match(line)
|
||||
if match:
|
||||
file = match.group(1)
|
||||
|
||||
match = diff_chunk_re.match(line)
|
||||
if match:
|
||||
start = int(match.group(1))
|
||||
len = int(match.group(2))
|
||||
end = start + len
|
||||
|
||||
if len > 0 and (file.endswith('.c') or file.endswith('.h') or file.endswith('.vala')):
|
||||
chunks.append({ 'file': file, 'start': start, 'end': end })
|
||||
|
||||
return chunks
|
||||
|
||||
def reformat_chunks(chunks, rewrite):
|
||||
# Creates temp file with INDENT-ON/OFF comments
|
||||
def create_temp_file(file, start, end):
|
||||
with open(file) as f:
|
||||
tmp = tempfile.NamedTemporaryFile()
|
||||
tmp.write(b'/** *INDENT-OFF* **/\n')
|
||||
for i, line in enumerate(f):
|
||||
if i == start - 2:
|
||||
tmp.write(b'/** *INDENT-ON* **/\n')
|
||||
|
||||
tmp.write(bytes(line, 'utf-8'))
|
||||
|
||||
if i == end - 2:
|
||||
tmp.write(b'/** *INDENT-OFF* **/\n')
|
||||
|
||||
tmp.seek(0)
|
||||
|
||||
return tmp
|
||||
|
||||
# Removes uncrustify INDENT-ON/OFF helper comments
|
||||
def remove_indent_comments(output):
|
||||
tmp = tempfile.NamedTemporaryFile()
|
||||
|
||||
for line in output:
|
||||
if line != b'/** *INDENT-OFF* **/\n' and line != b'/** *INDENT-ON* **/\n':
|
||||
tmp.write(line)
|
||||
|
||||
tmp.seek(0)
|
||||
|
||||
return tmp
|
||||
|
||||
changed = None
|
||||
|
||||
for chunk in chunks:
|
||||
# Add INDENT-ON/OFF comments
|
||||
tmp = create_temp_file(chunk['file'], chunk['start'], chunk['end'])
|
||||
|
||||
# uncrustify chunk
|
||||
proc = subprocess.Popen(["uncrustify", "-c", uncrustify_cfg, "-f", tmp.name], stdout=subprocess.PIPE)
|
||||
reindented = proc.stdout.readlines()
|
||||
proc.wait()
|
||||
if proc.returncode != 0:
|
||||
continue
|
||||
|
||||
tmp.close()
|
||||
|
||||
# Remove INDENT-ON/OFF comments
|
||||
formatted = remove_indent_comments(reindented)
|
||||
|
||||
if dry_run is True:
|
||||
# Show changes
|
||||
proc = subprocess.Popen(["diff", "-up", "--color=always", chunk['file'], formatted.name], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
diff = proc.stdout.read().decode('utf-8')
|
||||
if diff != '':
|
||||
output = re.sub('\t', '↦\t', diff)
|
||||
print(output)
|
||||
changed = True
|
||||
else:
|
||||
# Apply changes
|
||||
diff = subprocess.Popen(["diff", "-up", chunk['file'], formatted.name], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
patch = subprocess.Popen(["patch", chunk['file']], stdin=diff.stdout)
|
||||
diff.stdout.close()
|
||||
patch.communicate()
|
||||
|
||||
formatted.close()
|
||||
|
||||
return changed
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description='Check code style.')
|
||||
parser.add_argument('--sha', metavar='SHA', type=str,
|
||||
help='SHA for the commit to compare HEAD with')
|
||||
parser.add_argument('--dry-run', '-d', type=bool,
|
||||
action=argparse.BooleanOptionalAction,
|
||||
help='Only print changes to stdout, do not change code')
|
||||
parser.add_argument('--rewrite', '-r', type=bool,
|
||||
action=argparse.BooleanOptionalAction,
|
||||
help='Whether to amend the result to the last commit (e.g. \'git rebase --exec "%(prog)s -r"\')')
|
||||
|
||||
# Change CWD to script location, necessary for always locating the configuration file
|
||||
os.chdir(os.path.dirname(os.path.abspath(sys.argv[0])))
|
||||
|
||||
args = parser.parse_args()
|
||||
sha = args.sha or 'HEAD^'
|
||||
rewrite = args.rewrite
|
||||
dry_run = args.dry_run
|
||||
|
||||
diff = run_diff(sha)
|
||||
chunks = find_chunks(diff)
|
||||
changed = reformat_chunks(chunks, rewrite)
|
||||
|
||||
if dry_run is not True and rewrite is True:
|
||||
proc = subprocess.Popen(["git", "commit", "--all", "--amend", "-C", "HEAD"], stdout=subprocess.DEVNULL)
|
||||
os._exit(0)
|
||||
elif dry_run is True and changed is True:
|
||||
print ("\nIssue the following command in your local tree to apply the suggested changes (needs uncrustify installed):\n\n $ git rebase origin/main --exec \"./check-style.py -r\" \n")
|
||||
os._exit(-1)
|
||||
|
||||
os._exit(0)
|
@ -28,7 +28,7 @@
|
||||
#include "cally-actor.h"
|
||||
|
||||
/*
|
||||
* Auxiliary define, in order to get the clutter actor from the AtkObject using
|
||||
* Auxiliar define, in order to get the clutter actor from the AtkObject using
|
||||
* AtkGObject methods
|
||||
*
|
||||
*/
|
||||
|
@ -72,7 +72,9 @@
|
||||
#include <glib.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "clutter/clutter-actor-private.h"
|
||||
#ifdef CLUTTER_WINDOWING_X11
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@ -765,11 +767,10 @@ static gboolean
|
||||
cally_actor_action_do_action (AtkAction *action,
|
||||
gint index)
|
||||
{
|
||||
CallyActor *cally_actor = NULL;
|
||||
AtkStateSet *set = NULL;
|
||||
CallyActorPrivate *priv = NULL;
|
||||
CallyActorActionInfo *info = NULL;
|
||||
gboolean did_action = FALSE;
|
||||
CallyActor *cally_actor = NULL;
|
||||
AtkStateSet *set = NULL;
|
||||
CallyActorPrivate *priv = NULL;
|
||||
CallyActorActionInfo *info = NULL;
|
||||
|
||||
cally_actor = CALLY_ACTOR (action);
|
||||
priv = cally_actor->priv;
|
||||
@ -777,19 +778,21 @@ cally_actor_action_do_action (AtkAction *action,
|
||||
set = atk_object_ref_state_set (ATK_OBJECT (cally_actor));
|
||||
|
||||
if (atk_state_set_contains_state (set, ATK_STATE_DEFUNCT))
|
||||
goto out;
|
||||
return FALSE;
|
||||
|
||||
if (!atk_state_set_contains_state (set, ATK_STATE_SENSITIVE) ||
|
||||
!atk_state_set_contains_state (set, ATK_STATE_SHOWING))
|
||||
goto out;
|
||||
return FALSE;
|
||||
|
||||
g_object_unref (set);
|
||||
|
||||
info = _cally_actor_get_action_info (cally_actor, index);
|
||||
|
||||
if (info == NULL)
|
||||
goto out;
|
||||
return FALSE;
|
||||
|
||||
if (info->do_action_func == NULL)
|
||||
goto out;
|
||||
return FALSE;
|
||||
|
||||
if (!priv->action_queue)
|
||||
priv->action_queue = g_queue_new ();
|
||||
@ -799,12 +802,7 @@ cally_actor_action_do_action (AtkAction *action,
|
||||
if (!priv->action_idle_handler)
|
||||
priv->action_idle_handler = g_idle_add (idle_do_action, cally_actor);
|
||||
|
||||
did_action = TRUE;
|
||||
|
||||
out:
|
||||
g_clear_object (&set);
|
||||
|
||||
return did_action;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -970,7 +968,7 @@ cally_actor_real_notify_clutter (GObject *obj,
|
||||
* paint it; we don't want this to generate an ATK
|
||||
* state change
|
||||
*/
|
||||
if (clutter_actor_is_painting_unmapped (actor))
|
||||
if (clutter_actor_is_in_clone_paint (actor))
|
||||
return;
|
||||
|
||||
state = ATK_STATE_SHOWING;
|
||||
@ -1086,7 +1084,7 @@ cally_actor_add_action_full (CallyActor *cally_actor,
|
||||
|
||||
priv = cally_actor->priv;
|
||||
|
||||
info = g_new0 (CallyActorActionInfo, 1);
|
||||
info = g_slice_new (CallyActorActionInfo);
|
||||
info->name = g_strdup (action_name);
|
||||
info->description = g_strdup (action_description);
|
||||
info->keybinding = g_strdup (action_keybinding);
|
||||
@ -1106,7 +1104,7 @@ cally_actor_add_action_full (CallyActor *cally_actor,
|
||||
*
|
||||
* Removes a action, using the @action_id returned by cally_actor_add_action()
|
||||
*
|
||||
* Return value: %TRUE if the operation was successful, %FALSE otherwise
|
||||
* Return value: %TRUE if the operation was succesful, %FALSE otherwise
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
@ -1140,7 +1138,7 @@ cally_actor_remove_action (CallyActor *cally_actor,
|
||||
* Removes an action, using the @action_name used when the action was added
|
||||
* with cally_actor_add_action()
|
||||
*
|
||||
* Return value: %TRUE if the operation was successful, %FALSE otherwise
|
||||
* Return value: %TRUE if the operation was succesful, %FALSE otherwise
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
@ -1191,5 +1189,5 @@ _cally_actor_destroy_action_info (gpointer action_info,
|
||||
if (info->notify)
|
||||
info->notify (info->user_data);
|
||||
|
||||
g_free (info);
|
||||
g_slice_free (CallyActorActionInfo, info);
|
||||
}
|
||||
|
147
clutter/clutter/cally/cally-group.c
Normal file
147
clutter/clutter/cally/cally-group.c
Normal file
@ -0,0 +1,147 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* Based on GailContainer from GAIL
|
||||
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:cally-group
|
||||
* @Title: CallyGroup
|
||||
* @short_description: Implementation of the ATK interfaces for a #ClutterGroup
|
||||
* @see_also: #ClutterGroup
|
||||
*
|
||||
* #CallyGroup implements the required ATK interfaces of #ClutterGroup
|
||||
* In particular it exposes each of the Clutter actors contained in the
|
||||
* group.
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "cally-group.h"
|
||||
#include "cally-actor-private.h"
|
||||
|
||||
static gint cally_group_get_n_children (AtkObject *obj);
|
||||
static AtkObject* cally_group_ref_child (AtkObject *obj,
|
||||
gint i);
|
||||
static void cally_group_real_initialize (AtkObject *obj,
|
||||
gpointer data);
|
||||
|
||||
G_DEFINE_TYPE (CallyGroup, cally_group, CALLY_TYPE_ACTOR)
|
||||
|
||||
static void
|
||||
cally_group_class_init (CallyGroupClass *klass)
|
||||
{
|
||||
/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */
|
||||
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
|
||||
|
||||
class->get_n_children = cally_group_get_n_children;
|
||||
class->ref_child = cally_group_ref_child;
|
||||
class->initialize = cally_group_real_initialize;
|
||||
}
|
||||
|
||||
static void
|
||||
cally_group_init (CallyGroup *group)
|
||||
{
|
||||
/* nothing to do yet */
|
||||
}
|
||||
|
||||
/**
|
||||
* cally_group_new:
|
||||
* @actor: a #ClutterGroup
|
||||
*
|
||||
* Creates a #CallyGroup for @actor
|
||||
*
|
||||
* Return value: the newly created #CallyGroup
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
AtkObject *
|
||||
cally_group_new (ClutterActor *actor)
|
||||
{
|
||||
GObject *object = NULL;
|
||||
AtkObject *accessible = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_GROUP (actor), NULL);
|
||||
|
||||
object = g_object_new (CALLY_TYPE_GROUP, NULL);
|
||||
|
||||
accessible = ATK_OBJECT (object);
|
||||
atk_object_initialize (accessible, actor);
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
static gint
|
||||
cally_group_get_n_children (AtkObject *obj)
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
gint count = 0;
|
||||
|
||||
g_return_val_if_fail (CALLY_IS_GROUP (obj), count);
|
||||
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (obj);
|
||||
|
||||
if (actor == NULL) /* defunct */
|
||||
return 0;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_GROUP(actor), count);
|
||||
|
||||
count = clutter_actor_get_n_children (actor);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static AtkObject*
|
||||
cally_group_ref_child (AtkObject *obj,
|
||||
gint i)
|
||||
{
|
||||
AtkObject *accessible = NULL;
|
||||
ClutterActor *actor = NULL;
|
||||
ClutterActor *child = NULL;
|
||||
|
||||
g_return_val_if_fail (CALLY_IS_GROUP (obj), NULL);
|
||||
g_return_val_if_fail ((i >= 0), NULL);
|
||||
|
||||
actor = CALLY_GET_CLUTTER_ACTOR (obj);
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_GROUP(actor), NULL);
|
||||
child = clutter_actor_get_child_at_index (actor, i);
|
||||
|
||||
if (!child)
|
||||
return NULL;
|
||||
|
||||
accessible = clutter_actor_get_accessible (child);
|
||||
|
||||
if (accessible != NULL)
|
||||
g_object_ref (accessible);
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
static void
|
||||
cally_group_real_initialize (AtkObject *obj,
|
||||
gpointer data)
|
||||
{
|
||||
ATK_OBJECT_CLASS (cally_group_parent_class)->initialize (obj, data);
|
||||
|
||||
obj->role = ATK_ROLE_PANEL;
|
||||
}
|
87
clutter/clutter/cally/cally-group.h
Normal file
87
clutter/clutter/cally/cally-group.h
Normal file
@ -0,0 +1,87 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2008 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* Based on GailContainer from GAIL
|
||||
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CALLY_GROUP_H__
|
||||
#define __CALLY_GROUP_H__
|
||||
|
||||
#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <cally/cally.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <cally/cally-actor.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CALLY_TYPE_GROUP (cally_group_get_type ())
|
||||
#define CALLY_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_GROUP, CallyGroup))
|
||||
#define CALLY_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_GROUP, CallyGroupClass))
|
||||
#define CALLY_IS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_GROUP))
|
||||
#define CALLY_IS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_GROUP))
|
||||
#define CALLY_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_GROUP, CallyGroupClass))
|
||||
|
||||
typedef struct _CallyGroup CallyGroup;
|
||||
typedef struct _CallyGroupClass CallyGroupClass;
|
||||
typedef struct _CallyGroupPrivate CallyGroupPrivate;
|
||||
|
||||
/**
|
||||
* CallyGroup:
|
||||
*
|
||||
* The <structname>CallyGroup</structname> structure contains only
|
||||
* private data and should be accessed using the provided API
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _CallyGroup
|
||||
{
|
||||
/*< private >*/
|
||||
CallyActor parent;
|
||||
|
||||
CallyGroupPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* CallyGroupClass:
|
||||
*
|
||||
* The <structname>CallyGroupClass</structname> structure contains only
|
||||
* private data
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _CallyGroupClass
|
||||
{
|
||||
/*< private >*/
|
||||
CallyActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[8];
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType cally_group_get_type (void) G_GNUC_CONST;
|
||||
CLUTTER_EXPORT
|
||||
AtkObject* cally_group_new (ClutterActor *actor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CALLY_GROUP_H__ */
|
98
clutter/clutter/cally/cally-rectangle.c
Normal file
98
clutter/clutter/cally/cally-rectangle.c
Normal file
@ -0,0 +1,98 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2009 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:cally-rectangle
|
||||
* @short_description: Implementation of the ATK interfaces for a #ClutterRectangle
|
||||
* @see_also: #ClutterRectangle
|
||||
*
|
||||
* #CallyRectangle implements the required ATK interfaces of #ClutterRectangle
|
||||
*
|
||||
* In particular it sets a proper role for the rectangle.
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#include "cally-rectangle.h"
|
||||
#include "cally-actor-private.h"
|
||||
|
||||
#include "clutter-color.h"
|
||||
#include "deprecated/clutter-rectangle.h"
|
||||
|
||||
/* AtkObject */
|
||||
static void cally_rectangle_real_initialize (AtkObject *obj,
|
||||
gpointer data);
|
||||
|
||||
G_DEFINE_TYPE (CallyRectangle, cally_rectangle, CALLY_TYPE_ACTOR)
|
||||
|
||||
static void
|
||||
cally_rectangle_class_init (CallyRectangleClass *klass)
|
||||
{
|
||||
/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */
|
||||
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
|
||||
|
||||
class->initialize = cally_rectangle_real_initialize;
|
||||
}
|
||||
|
||||
static void
|
||||
cally_rectangle_init (CallyRectangle *rectangle)
|
||||
{
|
||||
/* nothing to do yet */
|
||||
}
|
||||
|
||||
/**
|
||||
* cally_rectangle_new:
|
||||
* @actor: a #ClutterActor
|
||||
*
|
||||
* Creates a new #CallyRectangle for the given @actor. @actor must be
|
||||
* a #ClutterRectangle.
|
||||
*
|
||||
* Return value: the newly created #AtkObject
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
AtkObject*
|
||||
cally_rectangle_new (ClutterActor *actor)
|
||||
{
|
||||
GObject *object = NULL;
|
||||
AtkObject *accessible = NULL;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_RECTANGLE (actor), NULL);
|
||||
|
||||
object = g_object_new (CALLY_TYPE_RECTANGLE, NULL);
|
||||
|
||||
accessible = ATK_OBJECT (object);
|
||||
atk_object_initialize (accessible, actor);
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
static void
|
||||
cally_rectangle_real_initialize (AtkObject *obj,
|
||||
gpointer data)
|
||||
{
|
||||
ATK_OBJECT_CLASS (cally_rectangle_parent_class)->initialize (obj, data);
|
||||
|
||||
obj->role = ATK_ROLE_IMAGE;
|
||||
}
|
84
clutter/clutter/cally/cally-rectangle.h
Normal file
84
clutter/clutter/cally/cally-rectangle.h
Normal file
@ -0,0 +1,84 @@
|
||||
/* CALLY - The Clutter Accessibility Implementation Library
|
||||
*
|
||||
* Copyright (C) 2009 Igalia, S.L.
|
||||
*
|
||||
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CALLY_RECTANGLE_H__
|
||||
#define __CALLY_RECTANGLE_H__
|
||||
|
||||
#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <cally/cally.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <cally/cally-actor.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CALLY_TYPE_RECTANGLE (cally_rectangle_get_type ())
|
||||
#define CALLY_RECTANGLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_RECTANGLE, CallyRectangle))
|
||||
#define CALLY_RECTANGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_RECTANGLE, CallyRectangleClass))
|
||||
#define CALLY_IS_RECTANGLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_RECTANGLE))
|
||||
#define CALLY_IS_RECTANGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_RECTANGLE))
|
||||
#define CALLY_RECTANGLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_RECTANGLE, CallyRectangleClass))
|
||||
|
||||
typedef struct _CallyRectangle CallyRectangle;
|
||||
typedef struct _CallyRectangleClass CallyRectangleClass;
|
||||
typedef struct _CallyRectanglePrivate CallyRectanglePrivate;
|
||||
|
||||
/**
|
||||
* CallyRectangle:
|
||||
*
|
||||
* The <structname>CallyRectangle</structname> structure contains only private
|
||||
* data and should be accessed using the provided API
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _CallyRectangle
|
||||
{
|
||||
/*< private >*/
|
||||
CallyActor parent;
|
||||
|
||||
CallyRectanglePrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* CallyRectangleClass:
|
||||
*
|
||||
* The <structname>CallyRectangleClass</structname> structure contains
|
||||
* only private data
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _CallyRectangleClass
|
||||
{
|
||||
/*< private >*/
|
||||
CallyActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[8];
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType cally_rectangle_get_type (void) G_GNUC_CONST;
|
||||
CLUTTER_EXPORT
|
||||
AtkObject* cally_rectangle_new (ClutterActor *actor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CALLY_RECTANGLE_H__ */
|
@ -47,7 +47,7 @@ static AtkStateSet* cally_stage_ref_state_set (AtkObject *obj);
|
||||
/* AtkWindow */
|
||||
static void cally_stage_window_interface_init (AtkWindowIface *iface);
|
||||
|
||||
/* Auxiliary */
|
||||
/* Auxiliar */
|
||||
static void cally_stage_activate_cb (ClutterStage *stage,
|
||||
gpointer data);
|
||||
static void cally_stage_deactivate_cb (ClutterStage *stage,
|
||||
@ -63,7 +63,7 @@ struct _CallyStagePrivate
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (CallyStage,
|
||||
cally_stage,
|
||||
CALLY_TYPE_ACTOR,
|
||||
CALLY_TYPE_GROUP,
|
||||
G_ADD_PRIVATE (CallyStage)
|
||||
G_IMPLEMENT_INTERFACE (ATK_TYPE_WINDOW,
|
||||
cally_stage_window_interface_init));
|
||||
@ -134,11 +134,8 @@ cally_stage_notify_key_focus_cb (ClutterStage *stage,
|
||||
|
||||
if (self->priv->key_focus != NULL)
|
||||
{
|
||||
if (self->priv->key_focus != CLUTTER_ACTOR (stage))
|
||||
{
|
||||
g_object_remove_weak_pointer (G_OBJECT (self->priv->key_focus),
|
||||
(gpointer *) &self->priv->key_focus);
|
||||
}
|
||||
g_object_remove_weak_pointer (G_OBJECT (self->priv->key_focus),
|
||||
(gpointer *) &self->priv->key_focus);
|
||||
old = clutter_actor_get_accessible (self->priv->key_focus);
|
||||
}
|
||||
else
|
||||
@ -163,11 +160,8 @@ cally_stage_notify_key_focus_cb (ClutterStage *stage,
|
||||
*
|
||||
* we remove the weak pointer above.
|
||||
*/
|
||||
if (key_focus != CLUTTER_ACTOR (stage))
|
||||
{
|
||||
g_object_add_weak_pointer (G_OBJECT (self->priv->key_focus),
|
||||
(gpointer *) &self->priv->key_focus);
|
||||
}
|
||||
g_object_add_weak_pointer (G_OBJECT (self->priv->key_focus),
|
||||
(gpointer *) &self->priv->key_focus);
|
||||
|
||||
new = clutter_actor_get_accessible (key_focus);
|
||||
}
|
||||
@ -228,7 +222,7 @@ cally_stage_window_interface_init (AtkWindowIface *iface)
|
||||
/* At this moment AtkWindow is just about signals */
|
||||
}
|
||||
|
||||
/* Auxiliary */
|
||||
/* Auxiliar */
|
||||
static void
|
||||
cally_stage_activate_cb (ClutterStage *stage,
|
||||
gpointer data)
|
||||
|
@ -25,7 +25,7 @@
|
||||
#error "Only <cally/cally.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <cally/cally-actor.h>
|
||||
#include <cally/cally-group.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@ -52,7 +52,7 @@ typedef struct _CallyStagePrivate CallyStagePrivate;
|
||||
struct _CallyStage
|
||||
{
|
||||
/*< private >*/
|
||||
CallyActor parent;
|
||||
CallyGroup parent;
|
||||
|
||||
CallyStagePrivate *priv;
|
||||
};
|
||||
@ -68,7 +68,7 @@ struct _CallyStage
|
||||
struct _CallyStageClass
|
||||
{
|
||||
/*< private >*/
|
||||
CallyActorClass parent_class;
|
||||
CallyGroupClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[16];
|
||||
|
@ -1513,7 +1513,7 @@ cally_text_get_offset_at_point (AtkText *text,
|
||||
}
|
||||
|
||||
|
||||
/******** Auxiliary private methods ******/
|
||||
/******** Auxiliar private methods ******/
|
||||
|
||||
/* ClutterText only maintains the current cursor position and a extra selection
|
||||
bound, but this could be before or after the cursor. This method returns
|
||||
@ -1552,7 +1552,7 @@ _cally_text_delete_text_cb (ClutterText *clutter_text,
|
||||
|
||||
g_return_if_fail (CALLY_IS_TEXT (data));
|
||||
|
||||
/* Ignore zero length deletions */
|
||||
/* Ignore zero lengh deletions */
|
||||
if (end_pos - start_pos == 0)
|
||||
return;
|
||||
|
||||
@ -1653,7 +1653,7 @@ cally_text_insert_text (AtkEditableText *text,
|
||||
clutter_text_insert_text (CLUTTER_TEXT (actor),
|
||||
string, *position);
|
||||
|
||||
/* we suppose that the text insertion will be successful,
|
||||
/* we suppose that the text insertion will be succesful,
|
||||
clutter-text doesn't warn about it. A option would be search for
|
||||
the text, but it seems not really required */
|
||||
*position += length;
|
||||
@ -1866,7 +1866,7 @@ static gint
|
||||
_cally_atk_attribute_lookup_func (gconstpointer data,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
AtkTextAttribute attr = (AtkTextAttribute) GPOINTER_TO_INT (user_data);
|
||||
AtkTextAttribute attr = (AtkTextAttribute) user_data;
|
||||
AtkAttribute *at = (AtkAttribute *) data;
|
||||
if (!g_strcmp0 (at->name, atk_text_attribute_get_name (attr)))
|
||||
return 0;
|
||||
|
@ -36,8 +36,10 @@
|
||||
#include "cally.h"
|
||||
|
||||
#include "cally-actor.h"
|
||||
#include "cally-group.h"
|
||||
#include "cally-stage.h"
|
||||
#include "cally-text.h"
|
||||
#include "cally-rectangle.h"
|
||||
#include "cally-clone.h"
|
||||
|
||||
#include "cally-factory.h"
|
||||
@ -50,8 +52,10 @@
|
||||
|
||||
/* factories initialization*/
|
||||
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_ACTOR, cally_actor, cally_actor_new)
|
||||
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_GROUP, cally_group, cally_group_new)
|
||||
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_STAGE, cally_stage, cally_stage_new)
|
||||
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_TEXT, cally_text, cally_text_new)
|
||||
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_RECTANGLE, cally_rectangle, cally_rectangle_new)
|
||||
CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_CLONE, cally_clone, cally_clone_new)
|
||||
|
||||
/**
|
||||
@ -69,8 +73,10 @@ cally_accessibility_init (void)
|
||||
{
|
||||
/* setting the factories */
|
||||
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_ACTOR, cally_actor);
|
||||
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_GROUP, cally_group);
|
||||
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_STAGE, cally_stage);
|
||||
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXT, cally_text);
|
||||
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_RECTANGLE, cally_rectangle);
|
||||
CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_CLONE, cally_clone);
|
||||
|
||||
/* Initialize the CallyUtility class */
|
||||
|
@ -26,7 +26,9 @@
|
||||
#include "cally-actor.h"
|
||||
#include "cally-clone.h"
|
||||
#include "cally-factory.h"
|
||||
#include "cally-group.h"
|
||||
#include "cally-main.h"
|
||||
#include "cally-rectangle.h"
|
||||
#include "cally-root.h"
|
||||
#include "cally-stage.h"
|
||||
#include "cally-text.h"
|
||||
|
@ -44,63 +44,18 @@
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter-action.h"
|
||||
#include "clutter-action-private.h"
|
||||
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
typedef struct _ClutterActionPrivate ClutterActionPrivate;
|
||||
|
||||
struct _ClutterActionPrivate
|
||||
{
|
||||
ClutterEventPhase phase;
|
||||
};
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterAction, clutter_action,
|
||||
CLUTTER_TYPE_ACTOR_META)
|
||||
|
||||
static gboolean
|
||||
clutter_action_handle_event_default (ClutterAction *action,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
G_DEFINE_ABSTRACT_TYPE (ClutterAction, clutter_action, CLUTTER_TYPE_ACTOR_META);
|
||||
|
||||
static void
|
||||
clutter_action_class_init (ClutterActionClass *klass)
|
||||
{
|
||||
klass->handle_event = clutter_action_handle_event_default;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_action_init (ClutterAction *self)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
clutter_action_set_phase (ClutterAction *action,
|
||||
ClutterEventPhase phase)
|
||||
{
|
||||
ClutterActionPrivate *priv;
|
||||
|
||||
priv = clutter_action_get_instance_private (action);
|
||||
priv->phase = phase;
|
||||
}
|
||||
|
||||
ClutterEventPhase
|
||||
clutter_action_get_phase (ClutterAction *action)
|
||||
{
|
||||
ClutterActionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTION (action), CLUTTER_PHASE_CAPTURE);
|
||||
|
||||
priv = clutter_action_get_instance_private (action);
|
||||
|
||||
return priv->phase;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_action_handle_event (ClutterAction *action,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
return CLUTTER_ACTION_GET_CLASS (action)->handle_event (action, event);
|
||||
}
|
||||
|
@ -51,9 +51,6 @@ struct _ClutterActionClass
|
||||
/*< private >*/
|
||||
ClutterActorMetaClass parent_class;
|
||||
|
||||
gboolean (* handle_event) (ClutterAction *action,
|
||||
const ClutterEvent *event);
|
||||
|
||||
void (* _clutter_action1) (void);
|
||||
void (* _clutter_action2) (void);
|
||||
void (* _clutter_action3) (void);
|
||||
@ -73,11 +70,6 @@ void clutter_actor_add_action_with_name (ClutterActor *self,
|
||||
const gchar *name,
|
||||
ClutterAction *action);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_add_action_full (ClutterActor *self,
|
||||
const char *name,
|
||||
ClutterEventPhase phase,
|
||||
ClutterAction *action);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_remove_action (ClutterActor *self,
|
||||
ClutterAction *action);
|
||||
CLUTTER_EXPORT
|
||||
@ -94,8 +86,6 @@ void clutter_actor_clear_actions (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_has_actions (ClutterActor *self);
|
||||
|
||||
ClutterEventPhase clutter_action_get_phase (ClutterAction *action);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ACTION_H__ */
|
||||
|
@ -54,7 +54,7 @@ clutter_actor_box_new (gfloat x_1,
|
||||
ClutterActorBox *
|
||||
clutter_actor_box_alloc (void)
|
||||
{
|
||||
return g_new0 (ClutterActorBox, 1);
|
||||
return g_slice_new0 (ClutterActorBox);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -130,7 +130,7 @@ ClutterActorBox *
|
||||
clutter_actor_box_copy (const ClutterActorBox *box)
|
||||
{
|
||||
if (G_LIKELY (box != NULL))
|
||||
return g_memdup2 (box, sizeof (ClutterActorBox));
|
||||
return g_slice_dup (ClutterActorBox, box);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -148,7 +148,7 @@ void
|
||||
clutter_actor_box_free (ClutterActorBox *box)
|
||||
{
|
||||
if (G_LIKELY (box != NULL))
|
||||
g_free (box);
|
||||
g_slice_free (ClutterActorBox, box);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -320,7 +320,7 @@ clutter_actor_box_get_area (const ClutterActorBox *box)
|
||||
* @y: Y coordinate of the point
|
||||
*
|
||||
* Checks whether a point with @x, @y coordinates is contained
|
||||
* within @box
|
||||
* withing @box
|
||||
*
|
||||
* Return value: %TRUE if the point is contained by the #ClutterActorBox
|
||||
*
|
||||
@ -554,7 +554,7 @@ _clutter_actor_box_enlarge_for_effects (ClutterActorBox *box)
|
||||
*
|
||||
* The reason this is important is because effects will use this
|
||||
* API to determine the size of offscreen framebuffers and so for
|
||||
* a fixed-size object that may be animated across the screen we
|
||||
* a fixed-size object that may be animated accross the screen we
|
||||
* want to make sure that the stage paint-box has an equally stable
|
||||
* size so that effects aren't made to continuously re-allocate
|
||||
* a corresponding fbo.
|
||||
@ -583,7 +583,7 @@ _clutter_actor_box_enlarge_for_effects (ClutterActorBox *box)
|
||||
|
||||
/* Now we redefine the top-left relative to the bottom right based on the
|
||||
* rounded width/height determined above + a constant so that the overall
|
||||
* size of the box will be stable and not dependent on the box's
|
||||
* size of the box will be stable and not dependant on the box's
|
||||
* position.
|
||||
*
|
||||
* Adding 3px to the width/height will ensure we cover the maximum of
|
||||
@ -615,32 +615,6 @@ clutter_actor_box_scale (ClutterActorBox *box,
|
||||
box->y2 *= scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_is_initialized:
|
||||
* @box: a #ClutterActorBox
|
||||
*
|
||||
* Checks if @box has been initialized, a #ClutterActorBox is uninitialized
|
||||
* if it has a size of -1 at an origin of 0, 0.
|
||||
*
|
||||
* Returns: %TRUE if the box is uninitialized, %FALSE if it isn't
|
||||
*/
|
||||
gboolean
|
||||
clutter_actor_box_is_initialized (ClutterActorBox *box)
|
||||
{
|
||||
gboolean x1_uninitialized, x2_uninitialized;
|
||||
gboolean y1_uninitialized, y2_uninitialized;
|
||||
|
||||
g_return_val_if_fail (box != NULL, TRUE);
|
||||
|
||||
x1_uninitialized = isinf (box->x1);
|
||||
x2_uninitialized = isinf (box->x2) && signbit (box->x2);
|
||||
y1_uninitialized = isinf (box->y1);
|
||||
y2_uninitialized = isinf (box->y2) && signbit (box->y2);
|
||||
|
||||
return !x1_uninitialized || !x2_uninitialized ||
|
||||
!y1_uninitialized || !y2_uninitialized;
|
||||
}
|
||||
|
||||
G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterActorBox, clutter_actor_box,
|
||||
clutter_actor_box_copy,
|
||||
clutter_actor_box_free,
|
||||
|
@ -26,6 +26,23 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*< private >
|
||||
* ClutterRedrawFlags:
|
||||
* @CLUTTER_REDRAW_CLIPPED_TO_ALLOCATION: Tells clutter the maximum
|
||||
* extents of what needs to be redrawn lies within the actors
|
||||
* current allocation. (Only use this for 2D actors though because
|
||||
* any actor with depth may be projected outside of its allocation)
|
||||
*
|
||||
* Flags passed to the clutter_actor_queue_redraw_with_clip ()
|
||||
* function
|
||||
*
|
||||
* Since: 1.6
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_REDRAW_CLIPPED_TO_ALLOCATION = 1 << 0
|
||||
} ClutterRedrawFlags;
|
||||
|
||||
/*< private >
|
||||
* ClutterActorTraverseFlags:
|
||||
* CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST: Traverse the graph in
|
||||
@ -93,12 +110,35 @@ typedef ClutterActorTraverseVisitFlags (*ClutterTraverseCallback) (ClutterActor
|
||||
typedef gboolean (*ClutterForeachCallback) (ClutterActor *actor,
|
||||
gpointer user_data);
|
||||
|
||||
typedef struct _AnchorCoord AnchorCoord;
|
||||
typedef struct _SizeRequest SizeRequest;
|
||||
|
||||
typedef struct _ClutterLayoutInfo ClutterLayoutInfo;
|
||||
typedef struct _ClutterTransformInfo ClutterTransformInfo;
|
||||
typedef struct _ClutterAnimationInfo ClutterAnimationInfo;
|
||||
|
||||
/* Internal helper struct to represent a point that can be stored in
|
||||
either direct pixel coordinates or as a fraction of the actor's
|
||||
size. It is used for the anchor point, scale center and rotation
|
||||
centers. */
|
||||
struct _AnchorCoord
|
||||
{
|
||||
gboolean is_fractional;
|
||||
|
||||
union
|
||||
{
|
||||
/* Used when is_fractional == TRUE */
|
||||
struct
|
||||
{
|
||||
gdouble x;
|
||||
gdouble y;
|
||||
} fraction;
|
||||
|
||||
/* Use when is_fractional == FALSE */
|
||||
graphene_point3d_t units;
|
||||
} v;
|
||||
};
|
||||
|
||||
struct _SizeRequest
|
||||
{
|
||||
guint age;
|
||||
@ -143,15 +183,24 @@ ClutterLayoutInfo * _clutter_actor_peek_layout_info
|
||||
|
||||
struct _ClutterTransformInfo
|
||||
{
|
||||
/* rotation */
|
||||
/* rotation (angle and center) */
|
||||
gdouble rx_angle;
|
||||
AnchorCoord rx_center;
|
||||
|
||||
gdouble ry_angle;
|
||||
AnchorCoord ry_center;
|
||||
|
||||
gdouble rz_angle;
|
||||
AnchorCoord rz_center;
|
||||
|
||||
/* scaling */
|
||||
gdouble scale_x;
|
||||
gdouble scale_y;
|
||||
gdouble scale_z;
|
||||
AnchorCoord scale_center;
|
||||
|
||||
/* anchor point */
|
||||
AnchorCoord anchor;
|
||||
|
||||
/* translation */
|
||||
graphene_point3d_t translation;
|
||||
@ -163,10 +212,10 @@ struct _ClutterTransformInfo
|
||||
graphene_point_t pivot;
|
||||
gfloat pivot_z;
|
||||
|
||||
graphene_matrix_t transform;
|
||||
CoglMatrix transform;
|
||||
guint transform_set : 1;
|
||||
|
||||
graphene_matrix_t child_transform;
|
||||
CoglMatrix child_transform;
|
||||
guint child_transform_set : 1;
|
||||
};
|
||||
|
||||
@ -203,11 +252,11 @@ void _clutter_actor_traverse
|
||||
gpointer user_data);
|
||||
ClutterActor * _clutter_actor_get_stage_internal (ClutterActor *actor);
|
||||
|
||||
void _clutter_actor_apply_modelview_transform (ClutterActor *self,
|
||||
graphene_matrix_t *matrix);
|
||||
void _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self,
|
||||
ClutterActor *ancestor,
|
||||
graphene_matrix_t *matrix);
|
||||
void _clutter_actor_apply_modelview_transform (ClutterActor *self,
|
||||
CoglMatrix *matrix);
|
||||
void _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self,
|
||||
ClutterActor *ancestor,
|
||||
CoglMatrix *matrix);
|
||||
|
||||
void _clutter_actor_rerealize (ClutterActor *self,
|
||||
ClutterCallback callback,
|
||||
@ -228,21 +277,30 @@ void _clutter_actor_set_has_pointer
|
||||
void _clutter_actor_set_has_key_focus (ClutterActor *self,
|
||||
gboolean has_key_focus);
|
||||
|
||||
void _clutter_actor_queue_redraw_with_clip (ClutterActor *self,
|
||||
ClutterRedrawFlags flags,
|
||||
const ClutterPaintVolume *clip_volume);
|
||||
void _clutter_actor_queue_redraw_full (ClutterActor *self,
|
||||
ClutterRedrawFlags flags,
|
||||
const ClutterPaintVolume *volume,
|
||||
ClutterEffect *effect);
|
||||
|
||||
void _clutter_actor_finish_queue_redraw (ClutterActor *self);
|
||||
void _clutter_actor_finish_queue_redraw (ClutterActor *self,
|
||||
ClutterPaintVolume *clip);
|
||||
|
||||
gboolean _clutter_actor_set_default_paint_volume (ClutterActor *self,
|
||||
GType check_gtype,
|
||||
ClutterPaintVolume *volume);
|
||||
|
||||
const char * _clutter_actor_get_debug_name (ClutterActor *self);
|
||||
const gchar * _clutter_actor_get_debug_name (ClutterActor *self);
|
||||
|
||||
void _clutter_actor_push_clone_paint (void);
|
||||
void _clutter_actor_pop_clone_paint (void);
|
||||
|
||||
void _clutter_actor_shader_pre_paint (ClutterActor *actor,
|
||||
gboolean repeat);
|
||||
void _clutter_actor_shader_post_paint (ClutterActor *actor);
|
||||
|
||||
ClutterActorAlign _clutter_actor_get_effective_x_align (ClutterActor *self);
|
||||
|
||||
void _clutter_actor_handle_event (ClutterActor *actor,
|
||||
@ -252,25 +310,17 @@ void _clutter_actor_attach_clone
|
||||
ClutterActor *clone);
|
||||
void _clutter_actor_detach_clone (ClutterActor *actor,
|
||||
ClutterActor *clone);
|
||||
void _clutter_actor_queue_redraw_on_clones (ClutterActor *actor);
|
||||
void _clutter_actor_queue_relayout_on_clones (ClutterActor *actor);
|
||||
void _clutter_actor_queue_only_relayout (ClutterActor *actor);
|
||||
void clutter_actor_clear_stage_views_recursive (ClutterActor *actor);
|
||||
void _clutter_actor_queue_update_resource_scale_recursive (ClutterActor *actor);
|
||||
|
||||
float clutter_actor_get_real_resource_scale (ClutterActor *actor);
|
||||
gboolean _clutter_actor_get_real_resource_scale (ClutterActor *actor,
|
||||
float *resource_scale);
|
||||
|
||||
ClutterPaintNode * clutter_actor_create_texture_paint_node (ClutterActor *self,
|
||||
CoglTexture *texture);
|
||||
|
||||
void clutter_actor_finish_layout (ClutterActor *self,
|
||||
int phase);
|
||||
|
||||
void clutter_actor_queue_immediate_relayout (ClutterActor *self);
|
||||
|
||||
gboolean clutter_actor_is_painting_unmapped (ClutterActor *self);
|
||||
|
||||
gboolean clutter_actor_get_redraw_clip (ClutterActor *self,
|
||||
ClutterPaintVolume *dst_old_pv,
|
||||
ClutterPaintVolume *dst_new_pv);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ACTOR_PRIVATE_H__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -142,6 +142,11 @@ struct _ClutterActor
|
||||
* ClutterActorClass:
|
||||
* @show: signal class handler for #ClutterActor::show; it must chain
|
||||
* up to the parent's implementation
|
||||
* @show_all: virtual function for containers and composite actors, to
|
||||
* determine which children should be shown when calling
|
||||
* clutter_actor_show_all() on the actor. Defaults to calling
|
||||
* clutter_actor_show(). This virtual function is deprecated and it
|
||||
* should not be overridden.
|
||||
* @hide: signal class handler for #ClutterActor::hide; it must chain
|
||||
* up to the parent's implementation
|
||||
* @hide_all: virtual function for containers and composite actors, to
|
||||
@ -178,15 +183,13 @@ struct _ClutterActor
|
||||
* implementation.
|
||||
* @apply_transform: virtual function, used when applying the transformations
|
||||
* to an actor before painting it or when transforming coordinates or
|
||||
* the allocation; if the transformation calculated by this function may
|
||||
* have changed, the cached transformation must be invalidated by calling
|
||||
* clutter_actor_invalidate_transform(); it must chain up to the parent's
|
||||
* implementation
|
||||
* the allocation; it must chain up to the parent's implementation
|
||||
* @parent_set: signal class handler for the #ClutterActor::parent-set
|
||||
* @destroy: signal class handler for #ClutterActor::destroy. It must
|
||||
* chain up to the parent's implementation
|
||||
* @pick: virtual function, used to draw an outline of the actor with
|
||||
* the given color
|
||||
* @queue_redraw: class handler for #ClutterActor::queue-redraw
|
||||
* @event: class handler for #ClutterActor::event
|
||||
* @button_press_event: class handler for #ClutterActor::button-press-event
|
||||
* @button_release_event: class handler for
|
||||
@ -223,6 +226,7 @@ struct _ClutterActorClass
|
||||
|
||||
/*< public >*/
|
||||
void (* show) (ClutterActor *self);
|
||||
void (* show_all) (ClutterActor *self);
|
||||
void (* hide) (ClutterActor *self);
|
||||
void (* hide_all) (ClutterActor *self);
|
||||
void (* realize) (ClutterActor *self);
|
||||
@ -238,6 +242,10 @@ struct _ClutterActorClass
|
||||
void (* pick) (ClutterActor *actor,
|
||||
ClutterPickContext *pick_context);
|
||||
|
||||
gboolean (* queue_redraw) (ClutterActor *actor,
|
||||
ClutterActor *leaf_that_queued,
|
||||
ClutterPaintVolume *paint_volume);
|
||||
|
||||
/* size negotiation */
|
||||
void (* get_preferred_width) (ClutterActor *self,
|
||||
gfloat for_height,
|
||||
@ -252,7 +260,7 @@ struct _ClutterActorClass
|
||||
|
||||
/* transformations */
|
||||
void (* apply_transform) (ClutterActor *actor,
|
||||
graphene_matrix_t *matrix);
|
||||
ClutterMatrix *matrix);
|
||||
|
||||
/* event signals */
|
||||
gboolean (* event) (ClutterActor *actor,
|
||||
@ -294,9 +302,6 @@ struct _ClutterActorClass
|
||||
gboolean (* touch_event) (ClutterActor *self,
|
||||
ClutterTouchEvent *event);
|
||||
gboolean (* has_accessible) (ClutterActor *self);
|
||||
void (* resource_scale_changed) (ClutterActor *self);
|
||||
float (* calculate_resource_scale) (ClutterActor *self,
|
||||
int phase);
|
||||
|
||||
/*< private >*/
|
||||
/* padding for future expansion */
|
||||
@ -414,9 +419,7 @@ CLUTTER_EXPORT
|
||||
void clutter_actor_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_allocate_preferred_size (ClutterActor *self,
|
||||
float x,
|
||||
float y);
|
||||
void clutter_actor_allocate_preferred_size (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_allocate_available_size (ClutterActor *self,
|
||||
gfloat x,
|
||||
@ -451,10 +454,6 @@ void clutter_actor_set_position
|
||||
gfloat x,
|
||||
gfloat y);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_get_fixed_position (ClutterActor *self,
|
||||
float *x,
|
||||
float *y);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_position (ClutterActor *self,
|
||||
gfloat *x,
|
||||
gfloat *y);
|
||||
@ -586,8 +585,7 @@ void clutter_actor_set_offscreen_redirect
|
||||
CLUTTER_EXPORT
|
||||
ClutterOffscreenRedirect clutter_actor_get_offscreen_redirect (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_should_pick (ClutterActor *self,
|
||||
ClutterPickContext *pick_context);
|
||||
gboolean clutter_actor_should_pick_paint (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_is_in_clone_paint (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
@ -595,7 +593,8 @@ gboolean clutter_actor_get_paint_box
|
||||
ClutterActorBox *box);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
float clutter_actor_get_resource_scale (ClutterActor *self);
|
||||
gboolean clutter_actor_get_resource_scale (ClutterActor *self,
|
||||
gfloat *resource_scale);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_has_overlaps (ClutterActor *self);
|
||||
@ -799,21 +798,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,
|
||||
@ -925,15 +919,6 @@ void clutter_actor_pick_box (ClutterActor *self,
|
||||
ClutterPickContext *pick_context,
|
||||
const ClutterActorBox *box);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GList * clutter_actor_peek_stage_views (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_invalidate_transform (ClutterActor *self);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_invalidate_paint_volume (ClutterActor *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ACTOR_H__ */
|
||||
|
@ -58,7 +58,6 @@ struct _ClutterAlignConstraint
|
||||
ClutterActor *actor;
|
||||
ClutterActor *source;
|
||||
ClutterAlignAxis align_axis;
|
||||
graphene_point_t pivot;
|
||||
gfloat factor;
|
||||
};
|
||||
|
||||
@ -73,7 +72,6 @@ enum
|
||||
|
||||
PROP_SOURCE,
|
||||
PROP_ALIGN_AXIS,
|
||||
PROP_PIVOT_POINT,
|
||||
PROP_FACTOR,
|
||||
|
||||
PROP_LAST
|
||||
@ -86,11 +84,12 @@ G_DEFINE_TYPE (ClutterAlignConstraint,
|
||||
CLUTTER_TYPE_CONSTRAINT);
|
||||
|
||||
static void
|
||||
source_queue_relayout (ClutterActor *actor,
|
||||
ClutterAlignConstraint *align)
|
||||
source_position_changed (ClutterActor *actor,
|
||||
GParamSpec *pspec,
|
||||
ClutterAlignConstraint *align)
|
||||
{
|
||||
if (align->actor != NULL)
|
||||
_clutter_actor_queue_only_relayout (align->actor);
|
||||
clutter_actor_queue_relayout (align->actor);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -135,41 +134,35 @@ clutter_align_constraint_update_allocation (ClutterConstraint *constraint,
|
||||
ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (constraint);
|
||||
gfloat source_width, source_height;
|
||||
gfloat actor_width, actor_height;
|
||||
gfloat offset_x_start, offset_y_start;
|
||||
gfloat pivot_x, pivot_y;
|
||||
gfloat source_x, source_y;
|
||||
|
||||
if (align->source == NULL)
|
||||
return;
|
||||
|
||||
clutter_actor_box_get_size (allocation, &actor_width, &actor_height);
|
||||
|
||||
clutter_actor_get_position (align->source, &source_x, &source_y);
|
||||
clutter_actor_get_size (align->source, &source_width, &source_height);
|
||||
|
||||
pivot_x = align->pivot.x == -1.f
|
||||
? align->factor
|
||||
: align->pivot.x;
|
||||
pivot_y = align->pivot.y == -1.f
|
||||
? align->factor
|
||||
: align->pivot.y;
|
||||
|
||||
offset_x_start = pivot_x * -actor_width;
|
||||
offset_y_start = pivot_y * -actor_height;
|
||||
|
||||
switch (align->align_axis)
|
||||
{
|
||||
case CLUTTER_ALIGN_X_AXIS:
|
||||
allocation->x1 += offset_x_start + (source_width * align->factor);
|
||||
allocation->x1 = ((source_width - actor_width) * align->factor)
|
||||
+ source_x;
|
||||
allocation->x2 = allocation->x1 + actor_width;
|
||||
break;
|
||||
|
||||
case CLUTTER_ALIGN_Y_AXIS:
|
||||
allocation->y1 += offset_y_start + (source_height * align->factor);
|
||||
allocation->y1 = ((source_height - actor_height) * align->factor)
|
||||
+ source_y;
|
||||
allocation->y2 = allocation->y1 + actor_height;
|
||||
break;
|
||||
|
||||
case CLUTTER_ALIGN_BOTH:
|
||||
allocation->x1 += offset_x_start + (source_width * align->factor);
|
||||
allocation->y1 += offset_y_start + (source_height * align->factor);
|
||||
allocation->x1 = ((source_width - actor_width) * align->factor)
|
||||
+ source_x;
|
||||
allocation->y1 = ((source_height - actor_height) * align->factor)
|
||||
+ source_y;
|
||||
allocation->x2 = allocation->x1 + actor_width;
|
||||
allocation->y2 = allocation->y1 + actor_height;
|
||||
break;
|
||||
@ -193,7 +186,7 @@ clutter_align_constraint_dispose (GObject *gobject)
|
||||
G_CALLBACK (source_destroyed),
|
||||
align);
|
||||
g_signal_handlers_disconnect_by_func (align->source,
|
||||
G_CALLBACK (source_queue_relayout),
|
||||
G_CALLBACK (source_position_changed),
|
||||
align);
|
||||
align->source = NULL;
|
||||
}
|
||||
@ -219,10 +212,6 @@ clutter_align_constraint_set_property (GObject *gobject,
|
||||
clutter_align_constraint_set_align_axis (align, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
case PROP_PIVOT_POINT:
|
||||
clutter_align_constraint_set_pivot_point (align, g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
case PROP_FACTOR:
|
||||
clutter_align_constraint_set_factor (align, g_value_get_float (value));
|
||||
break;
|
||||
@ -251,16 +240,6 @@ clutter_align_constraint_get_property (GObject *gobject,
|
||||
g_value_set_enum (value, align->align_axis);
|
||||
break;
|
||||
|
||||
case PROP_PIVOT_POINT:
|
||||
{
|
||||
graphene_point_t point;
|
||||
|
||||
clutter_align_constraint_get_pivot_point (align, &point);
|
||||
|
||||
g_value_set_boxed (value, &point);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_FACTOR:
|
||||
g_value_set_float (value, align->factor);
|
||||
break;
|
||||
@ -314,30 +293,6 @@ clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass)
|
||||
CLUTTER_ALIGN_X_AXIS,
|
||||
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT);
|
||||
|
||||
/**
|
||||
* ClutterAlignConstraint:pivot-point:
|
||||
*
|
||||
* The pivot point used by the constraint. The pivot point is the
|
||||
* point in the constraint actor around which the aligning is applied,
|
||||
* with (0, 0) being the top left corner of the actor and (1, 1) the
|
||||
* bottom right corner of the actor.
|
||||
*
|
||||
* For example, setting the pivot point to (0.5, 0.5) and using a factor
|
||||
* of 1 for both axes will align the actors horizontal and vertical
|
||||
* center point with the bottom right corner of the source actor.
|
||||
*
|
||||
* By default, the pivot point is set to (-1, -1), which means it's not
|
||||
* used and the constrained actor will be aligned to always stay inside
|
||||
* the source actor.
|
||||
*/
|
||||
obj_props[PROP_PIVOT_POINT] =
|
||||
g_param_spec_boxed ("pivot-point",
|
||||
P_("Pivot point"),
|
||||
P_("The pivot point"),
|
||||
GRAPHENE_TYPE_POINT,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterAlignConstraint:factor:
|
||||
*
|
||||
@ -370,8 +325,6 @@ clutter_align_constraint_init (ClutterAlignConstraint *self)
|
||||
self->actor = NULL;
|
||||
self->source = NULL;
|
||||
self->align_axis = CLUTTER_ALIGN_X_AXIS;
|
||||
self->pivot.x = -1.f;
|
||||
self->pivot.y = -1.f;
|
||||
self->factor = 0.0f;
|
||||
}
|
||||
|
||||
@ -449,15 +402,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, "notify::allocation",
|
||||
G_CALLBACK (source_position_changed),
|
||||
align);
|
||||
g_signal_connect (align->source, "destroy",
|
||||
G_CALLBACK (source_destroyed),
|
||||
@ -534,60 +487,6 @@ clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align)
|
||||
return align->align_axis;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_set_pivot_point:
|
||||
* @align: a #ClutterAlignConstraint
|
||||
* @pivot_point: A #GraphenePoint
|
||||
*
|
||||
* Sets the pivot point used by the constraint, the pivot point is the
|
||||
* point in the constraint actor around which the aligning is applied,
|
||||
* with (0, 0) being the top left corner of the actor and (1, 1) the
|
||||
* bottom right corner of the actor.
|
||||
*
|
||||
* If -1 is used, the pivot point is unset and the constrained actor
|
||||
* will be aligned to always stay inside the source actor.
|
||||
*/
|
||||
void
|
||||
clutter_align_constraint_set_pivot_point (ClutterAlignConstraint *align,
|
||||
const graphene_point_t *pivot_point)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
|
||||
g_return_if_fail (pivot_point != NULL);
|
||||
g_return_if_fail (pivot_point->x == -1.f ||
|
||||
(pivot_point->x >= 0.f && pivot_point->x <= 1.f));
|
||||
g_return_if_fail (pivot_point->y == -1.f ||
|
||||
(pivot_point->y >= 0.f && pivot_point->y <= 1.f));
|
||||
|
||||
if (graphene_point_equal (&align->pivot, pivot_point))
|
||||
return;
|
||||
|
||||
align->pivot = *pivot_point;
|
||||
|
||||
if (align->actor != NULL)
|
||||
clutter_actor_queue_relayout (align->actor);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_PIVOT_POINT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_get_pivot_point
|
||||
* @align: a #ClutterAlignConstraint
|
||||
* @pivot_point: (out caller-allocates): return location for a #GraphenePoint
|
||||
*
|
||||
* Gets the pivot point used by the constraint set with
|
||||
* clutter_align_constraint_set_pivot_point(). If no custom pivot
|
||||
* point is set, -1 is set.
|
||||
*/
|
||||
void
|
||||
clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align,
|
||||
graphene_point_t *pivot_point)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align));
|
||||
g_return_if_fail (pivot_point != NULL);
|
||||
|
||||
*pivot_point = align->pivot;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_align_constraint_set_factor:
|
||||
* @align: a #ClutterAlignConstraint
|
||||
|
@ -67,12 +67,6 @@ void clutter_align_constraint_set_align_axis (ClutterAlignConstrai
|
||||
CLUTTER_EXPORT
|
||||
ClutterAlignAxis clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_align_constraint_set_pivot_point (ClutterAlignConstraint *align,
|
||||
const graphene_point_t *pivot_point);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align,
|
||||
graphene_point_t *pivot_point);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_align_constraint_set_factor (ClutterAlignConstraint *align,
|
||||
gfloat factor);
|
||||
CLUTTER_EXPORT
|
||||
|
@ -194,25 +194,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);
|
||||
}
|
||||
|
@ -50,7 +50,6 @@ 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
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
@ -73,7 +72,6 @@ struct _ClutterAnimatableInterface
|
||||
ClutterInterval *interval,
|
||||
gdouble progress,
|
||||
GValue *value);
|
||||
ClutterActor * (* get_actor) (ClutterAnimatable *animatable);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
@ -94,9 +92,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__ */
|
||||
|
@ -83,6 +83,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterZoomAction, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorBox, clutter_actor_box_free)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColor, clutter_color_free)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMargin, clutter_margin_free)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMatrix, clutter_matrix_free)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintContext, clutter_paint_context_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintNode, clutter_paint_node_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintVolume, clutter_paint_volume_free)
|
||||
|
@ -53,8 +53,6 @@ struct _ClutterBackend
|
||||
gfloat units_per_em;
|
||||
gint32 units_serial;
|
||||
|
||||
float fallback_resource_scale;
|
||||
|
||||
ClutterStageWindow *stage_window;
|
||||
|
||||
ClutterInputMethod *input_method;
|
||||
@ -66,12 +64,18 @@ struct _ClutterBackendClass
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* vfuncs */
|
||||
gboolean (* finish_init) (ClutterBackend *backend,
|
||||
gboolean (* pre_parse) (ClutterBackend *backend,
|
||||
GError **error);
|
||||
gboolean (* post_parse) (ClutterBackend *backend,
|
||||
GError **error);
|
||||
ClutterStageWindow * (* create_stage) (ClutterBackend *backend,
|
||||
ClutterStage *wrapper,
|
||||
GError **error);
|
||||
void (* init_events) (ClutterBackend *backend);
|
||||
void (* init_features) (ClutterBackend *backend);
|
||||
void (* add_options) (ClutterBackend *backend,
|
||||
GOptionGroup *group);
|
||||
ClutterFeatureFlags (* get_features) (ClutterBackend *backend);
|
||||
CoglRenderer * (* get_renderer) (ClutterBackend *backend,
|
||||
GError **error);
|
||||
CoglDisplay * (* get_display) (ClutterBackend *backend,
|
||||
@ -87,28 +91,40 @@ struct _ClutterBackendClass
|
||||
|
||||
ClutterSeat * (* get_default_seat) (ClutterBackend *backend);
|
||||
|
||||
gboolean (* is_display_server) (ClutterBackend *backend);
|
||||
|
||||
/* signals */
|
||||
void (* resolution_changed) (ClutterBackend *backend);
|
||||
void (* font_changed) (ClutterBackend *backend);
|
||||
void (* settings_changed) (ClutterBackend *backend);
|
||||
};
|
||||
|
||||
ClutterBackend * _clutter_create_backend (void);
|
||||
|
||||
ClutterStageWindow * _clutter_backend_create_stage (ClutterBackend *backend,
|
||||
ClutterStage *wrapper,
|
||||
GError **error);
|
||||
gboolean _clutter_backend_create_context (ClutterBackend *backend,
|
||||
GError **error);
|
||||
|
||||
gboolean _clutter_backend_finish_init (ClutterBackend *backend,
|
||||
void _clutter_backend_add_options (ClutterBackend *backend,
|
||||
GOptionGroup *group);
|
||||
gboolean _clutter_backend_pre_parse (ClutterBackend *backend,
|
||||
GError **error);
|
||||
gboolean _clutter_backend_post_parse (ClutterBackend *backend,
|
||||
GError **error);
|
||||
|
||||
void _clutter_backend_init_events (ClutterBackend *backend);
|
||||
void _clutter_backend_copy_event_data (ClutterBackend *backend,
|
||||
const ClutterEvent *src,
|
||||
ClutterEvent *dest);
|
||||
void _clutter_backend_free_event_data (ClutterBackend *backend,
|
||||
ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
gboolean _clutter_backend_translate_event (ClutterBackend *backend,
|
||||
gpointer native,
|
||||
ClutterEvent *event);
|
||||
|
||||
ClutterFeatureFlags _clutter_backend_get_features (ClutterBackend *backend);
|
||||
|
||||
gfloat _clutter_backend_get_units_per_em (ClutterBackend *backend,
|
||||
PangoFontDescription *font_desc);
|
||||
gint32 _clutter_backend_get_units_serial (ClutterBackend *backend);
|
||||
@ -118,17 +134,6 @@ void clutter_set_allowed_drivers (const c
|
||||
CLUTTER_EXPORT
|
||||
ClutterStageWindow * clutter_backend_get_stage_window (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_backend_set_fallback_resource_scale (ClutterBackend *backend,
|
||||
float fallback_resource_scale);
|
||||
|
||||
float clutter_backend_get_fallback_resource_scale (ClutterBackend *backend);
|
||||
|
||||
gboolean clutter_backend_is_display_server (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_backend_destroy (ClutterBackend *backend);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_BACKEND_PRIVATE_H__ */
|
||||
|
@ -40,6 +40,8 @@
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||
|
||||
#include "clutter-backend-private.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-event-private.h"
|
||||
@ -50,8 +52,25 @@
|
||||
#include "clutter-stage-private.h"
|
||||
#include "clutter-stage-window.h"
|
||||
|
||||
#ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
|
||||
#include "wayland/clutter-wayland-compositor.h"
|
||||
#endif
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#ifdef CLUTTER_INPUT_X11
|
||||
#include "x11/clutter-backend-x11.h"
|
||||
#endif
|
||||
#ifdef CLUTTER_WINDOWING_EGL
|
||||
#include "egl/clutter-backend-eglnative.h"
|
||||
#endif
|
||||
|
||||
#ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
|
||||
#include <cogl/cogl-wayland-server.h>
|
||||
#include <wayland-server.h>
|
||||
#include "wayland/clutter-wayland-compositor.h"
|
||||
#endif
|
||||
|
||||
#define DEFAULT_FONT_NAME "Sans 10"
|
||||
|
||||
enum
|
||||
@ -67,6 +86,12 @@ G_DEFINE_ABSTRACT_TYPE (ClutterBackend, clutter_backend, G_TYPE_OBJECT)
|
||||
|
||||
static guint backend_signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
/* Global for being able to specify a compositor side wayland display
|
||||
* pointer before clutter initialization */
|
||||
#ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
|
||||
static struct wl_display *_wayland_compositor_display;
|
||||
#endif
|
||||
|
||||
static void
|
||||
clutter_backend_dispose (GObject *gobject)
|
||||
{
|
||||
@ -75,20 +100,28 @@ clutter_backend_dispose (GObject *gobject)
|
||||
/* clear the events still in the queue of the main context */
|
||||
_clutter_clear_events_queue ();
|
||||
|
||||
g_clear_object (&backend->dummy_onscreen);
|
||||
g_clear_pointer (&backend->dummy_onscreen, cogl_object_unref);
|
||||
if (backend->stage_window)
|
||||
{
|
||||
g_object_remove_weak_pointer (G_OBJECT (backend->stage_window),
|
||||
(gpointer *) &backend->stage_window);
|
||||
backend->stage_window = NULL;
|
||||
}
|
||||
|
||||
g_clear_pointer (&backend->cogl_source, g_source_destroy);
|
||||
g_clear_pointer (&backend->font_name, g_free);
|
||||
g_clear_pointer (&backend->font_options, cairo_font_options_destroy);
|
||||
G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_backend_finalize (GObject *gobject)
|
||||
{
|
||||
ClutterBackend *backend = CLUTTER_BACKEND (gobject);
|
||||
|
||||
g_source_destroy (backend->cogl_source);
|
||||
|
||||
g_free (backend->font_name);
|
||||
clutter_backend_set_font_options (backend, NULL);
|
||||
g_clear_object (&backend->input_method);
|
||||
|
||||
G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject);
|
||||
G_OBJECT_CLASS (clutter_backend_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static gfloat
|
||||
@ -189,20 +222,22 @@ clutter_backend_do_real_create_context (ClutterBackend *backend,
|
||||
{
|
||||
ClutterBackendClass *klass;
|
||||
CoglSwapChain *swap_chain;
|
||||
GError *internal_error;
|
||||
|
||||
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
||||
|
||||
swap_chain = NULL;
|
||||
internal_error = NULL;
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Creating Cogl renderer");
|
||||
backend->cogl_renderer = klass->get_renderer (backend, error);
|
||||
backend->cogl_renderer = klass->get_renderer (backend, &internal_error);
|
||||
|
||||
if (backend->cogl_renderer == NULL)
|
||||
goto error;
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Connecting the renderer");
|
||||
cogl_renderer_set_driver (backend->cogl_renderer, driver_id);
|
||||
if (!cogl_renderer_connect (backend->cogl_renderer, error))
|
||||
if (!cogl_renderer_connect (backend->cogl_renderer, &internal_error))
|
||||
goto error;
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Creating Cogl swap chain");
|
||||
@ -214,7 +249,7 @@ clutter_backend_do_real_create_context (ClutterBackend *backend,
|
||||
backend->cogl_display = klass->get_display (backend,
|
||||
backend->cogl_renderer,
|
||||
swap_chain,
|
||||
error);
|
||||
&internal_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -230,7 +265,7 @@ clutter_backend_do_real_create_context (ClutterBackend *backend,
|
||||
*/
|
||||
res = cogl_renderer_check_onscreen_template (backend->cogl_renderer,
|
||||
tmpl,
|
||||
error);
|
||||
&internal_error);
|
||||
|
||||
if (!res)
|
||||
goto error;
|
||||
@ -244,12 +279,17 @@ clutter_backend_do_real_create_context (ClutterBackend *backend,
|
||||
if (backend->cogl_display == NULL)
|
||||
goto error;
|
||||
|
||||
#ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
|
||||
cogl_wayland_display_set_compositor_display (backend->cogl_display,
|
||||
_wayland_compositor_display);
|
||||
#endif
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Setting up the display");
|
||||
if (!cogl_display_setup (backend->cogl_display, error))
|
||||
if (!cogl_display_setup (backend->cogl_display, &internal_error))
|
||||
goto error;
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Creating the Cogl context");
|
||||
backend->cogl_context = cogl_context_new (backend->cogl_display, error);
|
||||
backend->cogl_context = cogl_context_new (backend->cogl_display, &internal_error);
|
||||
if (backend->cogl_context == NULL)
|
||||
goto error;
|
||||
|
||||
@ -353,7 +393,8 @@ clutter_backend_real_create_context (ClutterBackend *backend,
|
||||
if (internal_error != NULL)
|
||||
g_propagate_error (error, internal_error);
|
||||
else
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
g_set_error_literal (error, CLUTTER_INIT_ERROR,
|
||||
CLUTTER_INIT_ERROR_BACKEND,
|
||||
"Unable to initialize the Clutter backend: no available drivers found.");
|
||||
|
||||
return FALSE;
|
||||
@ -365,12 +406,134 @@ clutter_backend_real_create_context (ClutterBackend *backend,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static ClutterFeatureFlags
|
||||
clutter_backend_real_get_features (ClutterBackend *backend)
|
||||
{
|
||||
ClutterFeatureFlags flags = 0;
|
||||
|
||||
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN))
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND, "Cogl supports multiple onscreen framebuffers");
|
||||
flags |= CLUTTER_FEATURE_STAGE_MULTIPLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND, "Cogl only supports one onscreen framebuffer");
|
||||
flags |= CLUTTER_FEATURE_STAGE_STATIC;
|
||||
}
|
||||
|
||||
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_THROTTLE))
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers throttling");
|
||||
flags |= CLUTTER_FEATURE_SWAP_THROTTLE;
|
||||
}
|
||||
else
|
||||
CLUTTER_NOTE (BACKEND, "Cogl doesn't support swap buffers throttling");
|
||||
|
||||
if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT))
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers complete events");
|
||||
flags |= CLUTTER_FEATURE_SWAP_EVENTS;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static const char *allowed_backends;
|
||||
|
||||
static ClutterBackend * (* custom_backend_func) (void);
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
ClutterBackend * (* create_backend) (void);
|
||||
} available_backends[] = {
|
||||
#ifdef CLUTTER_WINDOWING_X11
|
||||
{ CLUTTER_WINDOWING_X11, clutter_backend_x11_new },
|
||||
#endif
|
||||
#ifdef CLUTTER_WINDOWING_EGL
|
||||
{ CLUTTER_WINDOWING_EGL, clutter_backend_egl_native_new },
|
||||
#endif
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
void
|
||||
clutter_set_custom_backend_func (ClutterBackend *(* func) (void))
|
||||
{
|
||||
custom_backend_func = func;
|
||||
}
|
||||
|
||||
ClutterBackend *
|
||||
_clutter_create_backend (void)
|
||||
{
|
||||
const char *backends_list;
|
||||
ClutterBackend *retval;
|
||||
gboolean allow_any;
|
||||
char **backends;
|
||||
int i;
|
||||
|
||||
if (custom_backend_func)
|
||||
{
|
||||
retval = custom_backend_func ();
|
||||
|
||||
if (!retval)
|
||||
g_error ("Failed to create custom backend.");
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (allowed_backends == NULL)
|
||||
allowed_backends = "*";
|
||||
|
||||
allow_any = strstr (allowed_backends, "*") != NULL;
|
||||
|
||||
backends_list = g_getenv ("CLUTTER_BACKEND");
|
||||
if (backends_list == NULL)
|
||||
backends_list = allowed_backends;
|
||||
|
||||
backends = g_strsplit (backends_list, ",", 0);
|
||||
|
||||
retval = NULL;
|
||||
|
||||
for (i = 0; retval == NULL && backends[i] != NULL; i++)
|
||||
{
|
||||
const char *backend = backends[i];
|
||||
gboolean is_any = g_str_equal (backend, "*");
|
||||
int j;
|
||||
|
||||
for (j = 0; available_backends[j].name != NULL; j++)
|
||||
{
|
||||
if ((is_any && allow_any) ||
|
||||
(is_any && strstr (allowed_backends, available_backends[j].name)) ||
|
||||
g_str_equal (backend, available_backends[j].name))
|
||||
{
|
||||
retval = available_backends[j].create_backend ();
|
||||
if (retval != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev (backends);
|
||||
|
||||
if (retval == NULL)
|
||||
g_error ("No default Clutter backend found.");
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_backend_real_init_events (ClutterBackend *backend)
|
||||
{
|
||||
g_error ("Unknown input backend");
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_backend_class_init (ClutterBackendClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->dispose = clutter_backend_dispose;
|
||||
gobject_class->finalize = clutter_backend_finalize;
|
||||
|
||||
/**
|
||||
* ClutterBackend::resolution-changed:
|
||||
@ -426,7 +589,9 @@ clutter_backend_class_init (ClutterBackendClass *klass)
|
||||
klass->resolution_changed = clutter_backend_real_resolution_changed;
|
||||
klass->font_changed = clutter_backend_real_font_changed;
|
||||
|
||||
klass->init_events = clutter_backend_real_init_events;
|
||||
klass->create_context = clutter_backend_real_create_context;
|
||||
klass->get_features = clutter_backend_real_get_features;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -436,21 +601,47 @@ clutter_backend_init (ClutterBackend *self)
|
||||
self->units_serial = 1;
|
||||
|
||||
self->dummy_onscreen = NULL;
|
||||
|
||||
self->fallback_resource_scale = 1.f;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_backend_finish_init (ClutterBackend *backend,
|
||||
GError **error)
|
||||
void
|
||||
_clutter_backend_add_options (ClutterBackend *backend,
|
||||
GOptionGroup *group)
|
||||
{
|
||||
ClutterBackendClass *klass;
|
||||
|
||||
g_assert (CLUTTER_IS_BACKEND (backend));
|
||||
|
||||
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
||||
if (klass->finish_init)
|
||||
return klass->finish_init (backend, error);
|
||||
if (klass->add_options)
|
||||
klass->add_options (backend, group);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_backend_pre_parse (ClutterBackend *backend,
|
||||
GError **error)
|
||||
{
|
||||
ClutterBackendClass *klass;
|
||||
|
||||
g_assert (CLUTTER_IS_BACKEND (backend));
|
||||
|
||||
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
||||
if (klass->pre_parse)
|
||||
return klass->pre_parse (backend, error);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_backend_post_parse (ClutterBackend *backend,
|
||||
GError **error)
|
||||
{
|
||||
ClutterBackendClass *klass;
|
||||
|
||||
g_assert (CLUTTER_IS_BACKEND (backend));
|
||||
|
||||
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
||||
if (klass->post_parse)
|
||||
return klass->post_parse (backend, error);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -495,6 +686,57 @@ _clutter_backend_create_context (ClutterBackend *backend,
|
||||
return klass->create_context (backend, error);
|
||||
}
|
||||
|
||||
ClutterFeatureFlags
|
||||
_clutter_backend_get_features (ClutterBackend *backend)
|
||||
{
|
||||
ClutterBackendClass *klass;
|
||||
GError *error;
|
||||
|
||||
g_assert (CLUTTER_IS_BACKEND (backend));
|
||||
|
||||
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
||||
|
||||
/* we need to have a context here; so we create the
|
||||
* GL context first and the ask for features. if the
|
||||
* context already exists this should be a no-op
|
||||
*/
|
||||
error = NULL;
|
||||
if (klass->create_context != NULL)
|
||||
{
|
||||
gboolean res;
|
||||
|
||||
res = klass->create_context (backend, &error);
|
||||
if (!res)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
g_critical ("Unable to create a context: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
else
|
||||
g_critical ("Unable to create a context: unknown error");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (klass->get_features)
|
||||
return klass->get_features (backend);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_backend_init_events (ClutterBackend *backend)
|
||||
{
|
||||
ClutterBackendClass *klass;
|
||||
|
||||
g_assert (CLUTTER_IS_BACKEND (backend));
|
||||
|
||||
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
||||
klass->init_events (backend);
|
||||
}
|
||||
|
||||
gfloat
|
||||
_clutter_backend_get_units_per_em (ClutterBackend *backend,
|
||||
PangoFontDescription *font_desc)
|
||||
@ -509,6 +751,31 @@ _clutter_backend_get_units_per_em (ClutterBackend *backend,
|
||||
return backend->units_per_em;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_backend_copy_event_data (ClutterBackend *backend,
|
||||
const ClutterEvent *src,
|
||||
ClutterEvent *dest)
|
||||
{
|
||||
ClutterSeatClass *seat_class;
|
||||
ClutterSeat *seat;
|
||||
|
||||
seat = clutter_backend_get_default_seat (backend);
|
||||
seat_class = CLUTTER_SEAT_GET_CLASS (seat);
|
||||
seat_class->copy_event_data (seat, src, dest);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_backend_free_event_data (ClutterBackend *backend,
|
||||
ClutterEvent *event)
|
||||
{
|
||||
ClutterSeatClass *seat_class;
|
||||
ClutterSeat *seat;
|
||||
|
||||
seat = clutter_backend_get_default_seat (backend);
|
||||
seat_class = CLUTTER_SEAT_GET_CLASS (seat);
|
||||
seat_class->free_event_data (seat, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_get_default_backend:
|
||||
*
|
||||
@ -678,6 +945,31 @@ clutter_backend_get_cogl_context (ClutterBackend *backend)
|
||||
return backend->cogl_context;
|
||||
}
|
||||
|
||||
#ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
|
||||
/**
|
||||
* clutter_wayland_set_compositor_display:
|
||||
* @display: A compositor side struct wl_display pointer
|
||||
*
|
||||
* This informs Clutter of your compositor side Wayland display
|
||||
* object. This must be called before calling clutter_init().
|
||||
*
|
||||
* Since: 1.8
|
||||
* Stability: unstable
|
||||
*/
|
||||
void
|
||||
clutter_wayland_set_compositor_display (void *display)
|
||||
{
|
||||
if (_clutter_context_is_initialized ())
|
||||
{
|
||||
g_warning ("%s() can only be used before calling clutter_init()",
|
||||
G_STRFUNC);
|
||||
return;
|
||||
}
|
||||
|
||||
_wayland_compositor_display = display;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
clutter_set_allowed_drivers (const char *drivers)
|
||||
{
|
||||
@ -739,29 +1031,3 @@ clutter_backend_get_default_seat (ClutterBackend *backend)
|
||||
|
||||
return CLUTTER_BACKEND_GET_CLASS (backend)->get_default_seat (backend);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_backend_set_fallback_resource_scale (ClutterBackend *backend,
|
||||
float fallback_resource_scale)
|
||||
{
|
||||
backend->fallback_resource_scale = fallback_resource_scale;
|
||||
}
|
||||
|
||||
float
|
||||
clutter_backend_get_fallback_resource_scale (ClutterBackend *backend)
|
||||
{
|
||||
return backend->fallback_resource_scale;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_backend_is_display_server (ClutterBackend *backend)
|
||||
{
|
||||
return CLUTTER_BACKEND_GET_CLASS (backend)->is_display_server (backend);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_backend_destroy (ClutterBackend *backend)
|
||||
{
|
||||
g_object_run_dispose (G_OBJECT (backend));
|
||||
g_object_unref (backend);
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include <clutter/clutter-config.h>
|
||||
#include <clutter/clutter-keymap.h>
|
||||
#include <clutter/clutter-types.h>
|
||||
#include <clutter/clutter-seat.h>
|
||||
|
@ -59,7 +59,7 @@
|
||||
ClutterMargin *
|
||||
clutter_margin_new (void)
|
||||
{
|
||||
return g_new0 (ClutterMargin, 1);
|
||||
return g_slice_new0 (ClutterMargin);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,7 +77,7 @@ ClutterMargin *
|
||||
clutter_margin_copy (const ClutterMargin *margin_)
|
||||
{
|
||||
if (G_LIKELY (margin_ != NULL))
|
||||
return g_memdup2 (margin_, sizeof (ClutterMargin));
|
||||
return g_slice_dup (ClutterMargin, margin_);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -95,9 +95,198 @@ void
|
||||
clutter_margin_free (ClutterMargin *margin_)
|
||||
{
|
||||
if (G_LIKELY (margin_ != NULL))
|
||||
g_free (margin_);
|
||||
g_slice_free (ClutterMargin, margin_);
|
||||
}
|
||||
|
||||
G_DEFINE_BOXED_TYPE (ClutterMargin, clutter_margin,
|
||||
clutter_margin_copy,
|
||||
clutter_margin_free)
|
||||
|
||||
/**
|
||||
* ClutterMatrix:
|
||||
*
|
||||
* A type representing a 4x4 matrix.
|
||||
*
|
||||
* It is identicaly to #CoglMatrix.
|
||||
*
|
||||
* Since: 1.12
|
||||
*/
|
||||
|
||||
static gpointer
|
||||
clutter_matrix_copy (gpointer data)
|
||||
{
|
||||
return cogl_matrix_copy (data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_matrix_progress (const GValue *a,
|
||||
const GValue *b,
|
||||
gdouble progress,
|
||||
GValue *retval)
|
||||
{
|
||||
const ClutterMatrix *matrix1 = g_value_get_boxed (a);
|
||||
const ClutterMatrix *matrix2 = g_value_get_boxed (b);
|
||||
graphene_point3d_t scale1 = GRAPHENE_POINT3D_INIT (1.f, 1.f, 1.f);
|
||||
float shear1[3] = { 0.f, 0.f, 0.f };
|
||||
graphene_point3d_t rotate1 = GRAPHENE_POINT3D_INIT_ZERO;
|
||||
graphene_point3d_t translate1 = GRAPHENE_POINT3D_INIT_ZERO;
|
||||
ClutterVertex4 perspective1 = { 0.f, 0.f, 0.f, 0.f };
|
||||
graphene_point3d_t scale2 = GRAPHENE_POINT3D_INIT (1.f, 1.f, 1.f);
|
||||
float shear2[3] = { 0.f, 0.f, 0.f };
|
||||
graphene_point3d_t rotate2 = GRAPHENE_POINT3D_INIT_ZERO;
|
||||
graphene_point3d_t translate2 = GRAPHENE_POINT3D_INIT_ZERO;
|
||||
ClutterVertex4 perspective2 = { 0.f, 0.f, 0.f, 0.f };
|
||||
graphene_point3d_t scale_res = GRAPHENE_POINT3D_INIT (1.f, 1.f, 1.f);
|
||||
float shear_res = 0.f;
|
||||
graphene_point3d_t rotate_res = GRAPHENE_POINT3D_INIT_ZERO;
|
||||
graphene_point3d_t translate_res = GRAPHENE_POINT3D_INIT_ZERO;
|
||||
ClutterVertex4 perspective_res = { 0.f, 0.f, 0.f, 0.f };
|
||||
ClutterMatrix res;
|
||||
|
||||
clutter_matrix_init_identity (&res);
|
||||
|
||||
_clutter_util_matrix_decompose (matrix1,
|
||||
&scale1, shear1, &rotate1, &translate1,
|
||||
&perspective1);
|
||||
_clutter_util_matrix_decompose (matrix2,
|
||||
&scale2, shear2, &rotate2, &translate2,
|
||||
&perspective2);
|
||||
|
||||
/* perspective */
|
||||
_clutter_util_vertex4_interpolate (&perspective1, &perspective2, progress, &perspective_res);
|
||||
res.wx = perspective_res.x;
|
||||
res.wy = perspective_res.y;
|
||||
res.wz = perspective_res.z;
|
||||
res.ww = perspective_res.w;
|
||||
|
||||
/* translation */
|
||||
graphene_point3d_interpolate (&translate1, &translate2, progress, &translate_res);
|
||||
cogl_matrix_translate (&res, translate_res.x, translate_res.y, translate_res.z);
|
||||
|
||||
/* rotation */
|
||||
graphene_point3d_interpolate (&rotate1, &rotate2, progress, &rotate_res);
|
||||
cogl_matrix_rotate (&res, rotate_res.x, 1.0f, 0.0f, 0.0f);
|
||||
cogl_matrix_rotate (&res, rotate_res.y, 0.0f, 1.0f, 0.0f);
|
||||
cogl_matrix_rotate (&res, rotate_res.z, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
/* skew */
|
||||
shear_res = shear1[2] + (shear2[2] - shear1[2]) * progress; /* YZ */
|
||||
if (shear_res != 0.f)
|
||||
_clutter_util_matrix_skew_yz (&res, shear_res);
|
||||
|
||||
shear_res = shear1[1] + (shear2[1] - shear1[1]) * progress; /* XZ */
|
||||
if (shear_res != 0.f)
|
||||
_clutter_util_matrix_skew_xz (&res, shear_res);
|
||||
|
||||
shear_res = shear1[0] + (shear2[0] - shear1[0]) * progress; /* XY */
|
||||
if (shear_res != 0.f)
|
||||
_clutter_util_matrix_skew_xy (&res, shear_res);
|
||||
|
||||
/* scale */
|
||||
graphene_point3d_interpolate (&scale1, &scale2, progress, &scale_res);
|
||||
cogl_matrix_scale (&res, scale_res.x, scale_res.y, scale_res.z);
|
||||
|
||||
g_value_set_boxed (retval, &res);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterMatrix, clutter_matrix,
|
||||
clutter_matrix_copy,
|
||||
clutter_matrix_free,
|
||||
CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_matrix_progress))
|
||||
|
||||
/**
|
||||
* clutter_matrix_alloc:
|
||||
*
|
||||
* Allocates enough memory to hold a #ClutterMatrix.
|
||||
*
|
||||
* Return value: (transfer full): the newly allocated #ClutterMatrix
|
||||
*
|
||||
* Since: 1.12
|
||||
*/
|
||||
ClutterMatrix *
|
||||
clutter_matrix_alloc (void)
|
||||
{
|
||||
return g_new0 (ClutterMatrix, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_matrix_free:
|
||||
* @matrix: (allow-none): a #ClutterMatrix
|
||||
*
|
||||
* Frees the memory allocated by clutter_matrix_alloc().
|
||||
*
|
||||
* Since: 1.12
|
||||
*/
|
||||
void
|
||||
clutter_matrix_free (ClutterMatrix *matrix)
|
||||
{
|
||||
cogl_matrix_free (matrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_matrix_init_identity:
|
||||
* @matrix: a #ClutterMatrix
|
||||
*
|
||||
* Initializes @matrix with the identity matrix, i.e.:
|
||||
*
|
||||
* |[
|
||||
* .xx = 1.0, .xy = 0.0, .xz = 0.0, .xw = 0.0
|
||||
* .yx = 0.0, .yy = 1.0, .yz = 0.0, .yw = 0.0
|
||||
* .zx = 0.0, .zy = 0.0, .zz = 1.0, .zw = 0.0
|
||||
* .wx = 0.0, .wy = 0.0, .wz = 0.0, .ww = 1.0
|
||||
* ]|
|
||||
*
|
||||
* Return value: (transfer none): the initialized #ClutterMatrix
|
||||
*
|
||||
* Since: 1.12
|
||||
*/
|
||||
ClutterMatrix *
|
||||
clutter_matrix_init_identity (ClutterMatrix *matrix)
|
||||
{
|
||||
cogl_matrix_init_identity (matrix);
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_matrix_init_from_array:
|
||||
* @matrix: a #ClutterMatrix
|
||||
* @values: (array fixed-size=16): a C array of 16 floating point values,
|
||||
* representing a 4x4 matrix, with column-major order
|
||||
*
|
||||
* Initializes @matrix with the contents of a C array of floating point
|
||||
* values.
|
||||
*
|
||||
* Return value: (transfer none): the initialzed #ClutterMatrix
|
||||
*
|
||||
* Since: 1.12
|
||||
*/
|
||||
ClutterMatrix *
|
||||
clutter_matrix_init_from_array (ClutterMatrix *matrix,
|
||||
const float values[16])
|
||||
{
|
||||
cogl_matrix_init_from_array (matrix, values);
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_matrix_init_from_matrix:
|
||||
* @a: the #ClutterMatrix to initialize
|
||||
* @b: the #ClutterMatrix to copy
|
||||
*
|
||||
* Initializes the #ClutterMatrix @a with the contents of the
|
||||
* #ClutterMatrix @b.
|
||||
*
|
||||
* Return value: (transfer none): the initialized #ClutterMatrix
|
||||
*
|
||||
* Since: 1.12
|
||||
*/
|
||||
ClutterMatrix *
|
||||
clutter_matrix_init_from_matrix (ClutterMatrix *a,
|
||||
const ClutterMatrix *b)
|
||||
{
|
||||
return memcpy (a, b, sizeof (ClutterMatrix));
|
||||
}
|
||||
|
@ -35,7 +35,7 @@
|
||||
#undef CBZ_L2T_INTERPOLATION
|
||||
|
||||
/****************************************************************************
|
||||
* ClutterBezier -- representation of a cubic bezier curve *
|
||||
* ClutterBezier -- represenation of a cubic bezier curve *
|
||||
* (private; a building block for the public bspline object) *
|
||||
****************************************************************************/
|
||||
|
||||
@ -104,7 +104,7 @@ struct _ClutterBezier
|
||||
ClutterBezier *
|
||||
_clutter_bezier_new (void)
|
||||
{
|
||||
return g_new0 (ClutterBezier, 1);
|
||||
return g_slice_new0 (ClutterBezier);
|
||||
}
|
||||
|
||||
void
|
||||
@ -112,7 +112,7 @@ _clutter_bezier_free (ClutterBezier * b)
|
||||
{
|
||||
if (G_LIKELY (b))
|
||||
{
|
||||
g_free (b);
|
||||
g_slice_free (ClutterBezier, b);
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,7 +213,7 @@ sqrti (int number)
|
||||
* algorithm does not calculate the square root, but its reciprocal ('y'
|
||||
* below), which is only at the end turned to the inverse value. In order
|
||||
* for the algorithm to produce satisfactory results, the reciprocal value
|
||||
* must be represented with sufficient precision; the 16.16 we use
|
||||
* must be represented with sufficient precission; the 16.16 we use
|
||||
* elsewhere in clutter is not good enough, and 10.22 is used instead.
|
||||
*/
|
||||
_FixedT x;
|
||||
@ -236,7 +236,7 @@ sqrti (int number)
|
||||
/* Now, we convert the float to 10.22 fixed. We exploit the mechanism
|
||||
* described at http://www.d6.com/users/checker/pdfs/gdmfp.pdf.
|
||||
*
|
||||
* We want 22 bit fraction; a single precision float uses 23 bit
|
||||
* We want 22 bit fraction; a single precission float uses 23 bit
|
||||
* mantisa, so we only need to add 2^(23-22) (no need for the 1.5
|
||||
* multiplier as we are only dealing with positive numbers).
|
||||
*
|
||||
@ -256,7 +256,7 @@ sqrti (int number)
|
||||
flt2.i = (flt2.i >> 11) * (y_1 >> 11);
|
||||
|
||||
/* If the original argument is less than 342, we do another
|
||||
* iteration to improve precision (for arguments >= 342, the single
|
||||
* iteration to improve precission (for arguments >= 342, the single
|
||||
* iteration produces generally better results).
|
||||
*/
|
||||
if (x < 171)
|
||||
|
@ -38,14 +38,12 @@
|
||||
*
|
||||
* |[<!-- language="C" -->
|
||||
* // source
|
||||
* rect[0] = clutter_actor_new ();
|
||||
* clutter_actor_set_background_color (rect[0], &red_color);
|
||||
* rect[0] = clutter_rectangle_new_with_color (&red_color);
|
||||
* clutter_actor_set_position (rect[0], x_pos, y_pos);
|
||||
* clutter_actor_set_size (rect[0], 100, 100);
|
||||
*
|
||||
* // second rectangle
|
||||
* rect[1] = clutter_actor_new ();
|
||||
* clutter_actor_set_background_color (rect[1], &green_color);
|
||||
* rect[1] = clutter_rectangle_new_with_color (&green_color);
|
||||
* clutter_actor_set_size (rect[1], 100, 100);
|
||||
* clutter_actor_set_opacity (rect[1], 0);
|
||||
*
|
||||
@ -55,8 +53,7 @@
|
||||
* clutter_actor_add_constraint_with_name (rect[1], "green-y", constraint);
|
||||
*
|
||||
* // third rectangle
|
||||
* rect[2] = clutter_actor_new ();
|
||||
* clutter_actor_set_background_color (rect[2], &blue_color);
|
||||
* rect[2] = clutter_rectangle_new_with_color (&blue_color);
|
||||
* clutter_actor_set_size (rect[2], 100, 100);
|
||||
* clutter_actor_set_opacity (rect[2], 0);
|
||||
*
|
||||
@ -168,9 +165,6 @@ clutter_bind_constraint_update_preferred_size (ClutterConstraint *constraint,
|
||||
bind->coordinate == CLUTTER_BIND_ALL))
|
||||
return;
|
||||
|
||||
if (clutter_actor_contains (bind->source, actor))
|
||||
return;
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case CLUTTER_ORIENTATION_HORIZONTAL:
|
||||
|
@ -189,7 +189,7 @@ binding_entry_new (const gchar *name,
|
||||
|
||||
modifiers = modifiers & BINDING_MOD_MASK;
|
||||
|
||||
entry = g_new0 (ClutterBindingEntry, 1);
|
||||
entry = g_slice_new (ClutterBindingEntry);
|
||||
entry->key_val = key_val;
|
||||
entry->modifiers = modifiers;
|
||||
entry->name = (gchar *) g_intern_string (name);
|
||||
@ -221,7 +221,7 @@ binding_entry_free (gpointer data)
|
||||
|
||||
g_closure_unref (entry->closure);
|
||||
|
||||
g_free (entry);
|
||||
g_slice_free (ClutterBindingEntry, entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,8 @@
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||
|
||||
#include "clutter-blur-effect.h"
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
@ -79,6 +81,9 @@ struct _ClutterBlurEffect
|
||||
|
||||
gint pixel_step_uniform;
|
||||
|
||||
gint tex_width;
|
||||
gint tex_height;
|
||||
|
||||
CoglPipeline *pipeline;
|
||||
};
|
||||
|
||||
@ -93,42 +98,20 @@ G_DEFINE_TYPE (ClutterBlurEffect,
|
||||
clutter_blur_effect,
|
||||
CLUTTER_TYPE_OFFSCREEN_EFFECT);
|
||||
|
||||
static CoglPipeline *
|
||||
clutter_blur_effect_create_pipeline (ClutterOffscreenEffect *effect,
|
||||
CoglTexture *texture)
|
||||
{
|
||||
ClutterBlurEffect *blur_effect = CLUTTER_BLUR_EFFECT (effect);
|
||||
|
||||
if (blur_effect->pixel_step_uniform > -1)
|
||||
{
|
||||
float pixel_step[2];
|
||||
int tex_width, tex_height;
|
||||
|
||||
tex_width = cogl_texture_get_width (texture);
|
||||
tex_height = cogl_texture_get_height (texture);
|
||||
|
||||
pixel_step[0] = 1.0f / tex_width;
|
||||
pixel_step[1] = 1.0f / tex_height;
|
||||
|
||||
cogl_pipeline_set_uniform_float (blur_effect->pipeline,
|
||||
blur_effect->pixel_step_uniform,
|
||||
2, /* n_components */
|
||||
1, /* count */
|
||||
pixel_step);
|
||||
}
|
||||
|
||||
cogl_pipeline_set_layer_texture (blur_effect->pipeline, 0, texture);
|
||||
|
||||
return cogl_object_ref (blur_effect->pipeline);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_blur_effect_pre_paint (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect);
|
||||
ClutterEffectClass *parent_class;
|
||||
|
||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
|
||||
return FALSE;
|
||||
|
||||
self->actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
|
||||
if (self->actor == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
|
||||
{
|
||||
/* if we don't have support for GLSL shaders then we
|
||||
@ -142,7 +125,59 @@ clutter_blur_effect_pre_paint (ClutterEffect *effect,
|
||||
}
|
||||
|
||||
parent_class = CLUTTER_EFFECT_CLASS (clutter_blur_effect_parent_class);
|
||||
return parent_class->pre_paint (effect, node, paint_context);
|
||||
if (parent_class->pre_paint (effect, paint_context))
|
||||
{
|
||||
ClutterOffscreenEffect *offscreen_effect =
|
||||
CLUTTER_OFFSCREEN_EFFECT (effect);
|
||||
CoglHandle texture;
|
||||
|
||||
texture = clutter_offscreen_effect_get_texture (offscreen_effect);
|
||||
self->tex_width = cogl_texture_get_width (texture);
|
||||
self->tex_height = cogl_texture_get_height (texture);
|
||||
|
||||
if (self->pixel_step_uniform > -1)
|
||||
{
|
||||
gfloat pixel_step[2];
|
||||
|
||||
pixel_step[0] = 1.0f / self->tex_width;
|
||||
pixel_step[1] = 1.0f / self->tex_height;
|
||||
|
||||
cogl_pipeline_set_uniform_float (self->pipeline,
|
||||
self->pixel_step_uniform,
|
||||
2, /* n_components */
|
||||
1, /* count */
|
||||
pixel_step);
|
||||
}
|
||||
|
||||
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect);
|
||||
CoglFramebuffer *framebuffer =
|
||||
clutter_paint_context_get_framebuffer (paint_context);
|
||||
guint8 paint_opacity;
|
||||
|
||||
paint_opacity = clutter_actor_get_paint_opacity (self->actor);
|
||||
|
||||
cogl_pipeline_set_color4ub (self->pipeline,
|
||||
paint_opacity,
|
||||
paint_opacity,
|
||||
paint_opacity,
|
||||
paint_opacity);
|
||||
|
||||
cogl_framebuffer_draw_rectangle (framebuffer,
|
||||
self->pipeline,
|
||||
0, 0,
|
||||
self->tex_width, self->tex_height);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -194,7 +229,7 @@ clutter_blur_effect_class_init (ClutterBlurEffectClass *klass)
|
||||
effect_class->modify_paint_volume = clutter_blur_effect_modify_paint_volume;
|
||||
|
||||
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
||||
offscreen_class->create_pipeline = clutter_blur_effect_create_pipeline;
|
||||
offscreen_class->paint_target = clutter_blur_effect_paint_target;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Endless OS Foundation, LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CLUTTER_BLUR_PRIVATE_H
|
||||
#define CLUTTER_BLUR_PRIVATE_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _ClutterBlur ClutterBlur;
|
||||
|
||||
ClutterBlur * clutter_blur_new (CoglTexture *texture,
|
||||
float sigma);
|
||||
|
||||
void clutter_blur_apply (ClutterBlur *blur);
|
||||
|
||||
CoglTexture * clutter_blur_get_texture (ClutterBlur *blur);
|
||||
|
||||
void clutter_blur_free (ClutterBlur *blur);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* CLUTTER_BLUR_PRIVATE_H */
|
@ -1,431 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Endless OS Foundation, LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "clutter-blur-private.h"
|
||||
|
||||
#include "clutter-backend.h"
|
||||
|
||||
/**
|
||||
* SECTION:clutter-blur
|
||||
* @short_description: Blur textures
|
||||
*
|
||||
* #ClutterBlur is a moderately fast gaussian blur implementation.
|
||||
*
|
||||
* # Optimizations
|
||||
*
|
||||
* There are a number of optimizations in place to make this blur implementation
|
||||
* real-time. All in all, the implementation performs best when using large
|
||||
* blur-radii that allow downscaling the texture to smaller sizes, at small
|
||||
* radii where no downscaling is possible this can easily halve the framerate.
|
||||
*
|
||||
* ## Multipass
|
||||
*
|
||||
* It is implemented in 2 passes: vertical and horizontal.
|
||||
*
|
||||
* ## Downscaling
|
||||
*
|
||||
* #ClutterBlur uses dynamic downscaling to speed up blurring. Downscaling
|
||||
* happens in factors of 2 (the image is downscaled either by 2, 4, 8, 16, …)
|
||||
* and depends on the blur radius, the texture size, among others.
|
||||
*
|
||||
* The texture is drawn into a downscaled framebuffer; the blur passes are
|
||||
* applied on the downscaled texture contents; and finally, the blurred
|
||||
* contents are drawn
|
||||
* upscaled again.
|
||||
*
|
||||
* ## Hardware Interpolation
|
||||
*
|
||||
* This blur implementation cuts down the number of sampling operations by
|
||||
* exploiting the hardware interpolation that is performed when sampling between
|
||||
* pixel boundaries. This technique is described at:
|
||||
*
|
||||
* http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
|
||||
*
|
||||
* ## Incremental gauss-factor calculation
|
||||
*
|
||||
* The kernel values for the gaussian kernel are computed incrementally instead
|
||||
* of running the expensive calculations multiple times inside the blur shader.
|
||||
* The implementation is based on the algorithm presented by K. Turkowski in
|
||||
* GPU Gems 3, chapter 40:
|
||||
*
|
||||
* https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch40.html
|
||||
*
|
||||
*/
|
||||
|
||||
static const char *gaussian_blur_glsl_declarations =
|
||||
"uniform float sigma; \n"
|
||||
"uniform float pixel_step; \n"
|
||||
"uniform vec2 direction; \n";
|
||||
|
||||
static const char *gaussian_blur_glsl =
|
||||
" vec2 uv = vec2 (cogl_tex_coord.st); \n"
|
||||
" \n"
|
||||
" vec3 gauss_coefficient; \n"
|
||||
" gauss_coefficient.x = 1.0 / (sqrt (2.0 * 3.14159265) * sigma); \n"
|
||||
" gauss_coefficient.y = exp (-0.5 / (sigma * sigma)); \n"
|
||||
" gauss_coefficient.z = gauss_coefficient.y * gauss_coefficient.y; \n"
|
||||
" \n"
|
||||
" float gauss_coefficient_total = gauss_coefficient.x; \n"
|
||||
" \n"
|
||||
" vec4 ret = texture2D (cogl_sampler, uv) * gauss_coefficient.x; \n"
|
||||
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
|
||||
" \n"
|
||||
" int n_steps = int (ceil (1.5 * sigma)) * 2; \n"
|
||||
" \n"
|
||||
" for (int i = 1; i <= n_steps; i += 2) { \n"
|
||||
" float coefficient_subtotal = gauss_coefficient.x; \n"
|
||||
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
|
||||
" coefficient_subtotal += gauss_coefficient.x; \n"
|
||||
" \n"
|
||||
" float gauss_ratio = gauss_coefficient.x / coefficient_subtotal; \n"
|
||||
" \n"
|
||||
" float foffset = float (i) + gauss_ratio; \n"
|
||||
" vec2 offset = direction * foffset * pixel_step; \n"
|
||||
" \n"
|
||||
" ret += texture2D (cogl_sampler, uv + offset) * coefficient_subtotal; \n"
|
||||
" ret += texture2D (cogl_sampler, uv - offset) * coefficient_subtotal; \n"
|
||||
" \n"
|
||||
" gauss_coefficient_total += 2.0 * coefficient_subtotal; \n"
|
||||
" gauss_coefficient.xy *= gauss_coefficient.yz; \n"
|
||||
" } \n"
|
||||
" \n"
|
||||
" cogl_texel = ret / gauss_coefficient_total; \n";
|
||||
|
||||
#define MIN_DOWNSCALE_SIZE 256.f
|
||||
#define MAX_SIGMA 6.f
|
||||
|
||||
enum
|
||||
{
|
||||
VERTICAL,
|
||||
HORIZONTAL,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglPipeline *pipeline;
|
||||
CoglTexture *texture;
|
||||
int orientation;
|
||||
} BlurPass;
|
||||
|
||||
struct _ClutterBlur
|
||||
{
|
||||
CoglTexture *source_texture;
|
||||
float sigma;
|
||||
float downscale_factor;
|
||||
|
||||
BlurPass pass[2];
|
||||
};
|
||||
|
||||
static CoglPipeline*
|
||||
create_blur_pipeline (void)
|
||||
{
|
||||
static CoglPipelineKey blur_pipeline_key = "clutter-blur-pipeline-private";
|
||||
CoglContext *ctx =
|
||||
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
CoglPipeline *blur_pipeline;
|
||||
|
||||
blur_pipeline =
|
||||
cogl_context_get_named_pipeline (ctx, &blur_pipeline_key);
|
||||
|
||||
if (G_UNLIKELY (blur_pipeline == NULL))
|
||||
{
|
||||
CoglSnippet *snippet;
|
||||
|
||||
blur_pipeline = cogl_pipeline_new (ctx);
|
||||
cogl_pipeline_set_layer_null_texture (blur_pipeline, 0);
|
||||
cogl_pipeline_set_layer_filters (blur_pipeline,
|
||||
0,
|
||||
COGL_PIPELINE_FILTER_LINEAR,
|
||||
COGL_PIPELINE_FILTER_LINEAR);
|
||||
cogl_pipeline_set_layer_wrap_mode (blur_pipeline,
|
||||
0,
|
||||
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
|
||||
|
||||
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
|
||||
gaussian_blur_glsl_declarations,
|
||||
NULL);
|
||||
cogl_snippet_set_replace (snippet, gaussian_blur_glsl);
|
||||
cogl_pipeline_add_layer_snippet (blur_pipeline, 0, snippet);
|
||||
cogl_object_unref (snippet);
|
||||
|
||||
cogl_context_set_named_pipeline (ctx, &blur_pipeline_key, blur_pipeline);
|
||||
}
|
||||
|
||||
return cogl_pipeline_copy (blur_pipeline);
|
||||
}
|
||||
|
||||
static void
|
||||
update_blur_uniforms (ClutterBlur *blur,
|
||||
BlurPass *pass)
|
||||
{
|
||||
gboolean vertical = pass->orientation == VERTICAL;
|
||||
int sigma_uniform;
|
||||
int pixel_step_uniform;
|
||||
int direction_uniform;
|
||||
|
||||
pixel_step_uniform =
|
||||
cogl_pipeline_get_uniform_location (pass->pipeline, "pixel_step");
|
||||
if (pixel_step_uniform > -1)
|
||||
{
|
||||
float pixel_step;
|
||||
|
||||
if (vertical)
|
||||
pixel_step = 1.f / cogl_texture_get_height (pass->texture);
|
||||
else
|
||||
pixel_step = 1.f / cogl_texture_get_width (pass->texture);
|
||||
|
||||
cogl_pipeline_set_uniform_1f (pass->pipeline,
|
||||
pixel_step_uniform,
|
||||
pixel_step);
|
||||
}
|
||||
|
||||
sigma_uniform = cogl_pipeline_get_uniform_location (pass->pipeline, "sigma");
|
||||
if (sigma_uniform > -1)
|
||||
{
|
||||
cogl_pipeline_set_uniform_1f (pass->pipeline,
|
||||
sigma_uniform,
|
||||
blur->sigma / blur->downscale_factor);
|
||||
}
|
||||
|
||||
direction_uniform =
|
||||
cogl_pipeline_get_uniform_location (pass->pipeline, "direction");
|
||||
if (direction_uniform > -1)
|
||||
{
|
||||
gboolean horizontal = !vertical;
|
||||
float direction[2] = {
|
||||
horizontal,
|
||||
vertical,
|
||||
};
|
||||
|
||||
cogl_pipeline_set_uniform_float (pass->pipeline,
|
||||
direction_uniform,
|
||||
2, 1,
|
||||
direction);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
create_fbo (ClutterBlur *blur,
|
||||
BlurPass *pass)
|
||||
{
|
||||
CoglContext *ctx =
|
||||
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
float scaled_height;
|
||||
float scaled_width;
|
||||
float height;
|
||||
float width;
|
||||
|
||||
g_clear_pointer (&pass->texture, cogl_object_unref);
|
||||
g_clear_object (&pass->framebuffer);
|
||||
|
||||
width = cogl_texture_get_width (blur->source_texture);
|
||||
height = cogl_texture_get_height (blur->source_texture);
|
||||
scaled_width = floorf (width / blur->downscale_factor);
|
||||
scaled_height = floorf (height / blur->downscale_factor);
|
||||
|
||||
pass->texture = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx,
|
||||
scaled_width,
|
||||
scaled_height));
|
||||
if (!pass->texture)
|
||||
return FALSE;
|
||||
|
||||
pass->framebuffer =
|
||||
COGL_FRAMEBUFFER (cogl_offscreen_new_with_texture (pass->texture));
|
||||
if (!pass->framebuffer)
|
||||
{
|
||||
g_warning ("%s: Unable to create an Offscreen buffer", G_STRLOC);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cogl_framebuffer_orthographic (pass->framebuffer,
|
||||
0.0, 0.0,
|
||||
scaled_width,
|
||||
scaled_height,
|
||||
0.0, 1.0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
setup_blur_pass (ClutterBlur *blur,
|
||||
BlurPass *pass,
|
||||
int orientation,
|
||||
CoglTexture *texture)
|
||||
{
|
||||
pass->orientation = orientation;
|
||||
pass->pipeline = create_blur_pipeline ();
|
||||
cogl_pipeline_set_layer_texture (pass->pipeline, 0, texture);
|
||||
|
||||
if (!create_fbo (blur, pass))
|
||||
return FALSE;
|
||||
|
||||
update_blur_uniforms (blur, pass);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static float
|
||||
calculate_downscale_factor (float width,
|
||||
float height,
|
||||
float sigma)
|
||||
{
|
||||
float downscale_factor = 1.f;
|
||||
float scaled_width = width;
|
||||
float scaled_height = height;
|
||||
float scaled_sigma = sigma;
|
||||
|
||||
/* This is the algorithm used by Firefox; keep downscaling until either the
|
||||
* blur radius is lower than the threshold, or the downscaled texture is too
|
||||
* small.
|
||||
*/
|
||||
while (scaled_sigma > MAX_SIGMA &&
|
||||
scaled_width > MIN_DOWNSCALE_SIZE &&
|
||||
scaled_height > MIN_DOWNSCALE_SIZE)
|
||||
{
|
||||
downscale_factor *= 2.f;
|
||||
|
||||
scaled_width = width / downscale_factor;
|
||||
scaled_height = height / downscale_factor;
|
||||
scaled_sigma = sigma / downscale_factor;
|
||||
}
|
||||
|
||||
return downscale_factor;
|
||||
}
|
||||
|
||||
static void
|
||||
apply_blur_pass (BlurPass *pass)
|
||||
{
|
||||
CoglColor transparent;
|
||||
|
||||
cogl_color_init_from_4ub (&transparent, 0, 0, 0, 0);
|
||||
|
||||
cogl_framebuffer_clear (pass->framebuffer,
|
||||
COGL_BUFFER_BIT_COLOR,
|
||||
&transparent);
|
||||
|
||||
cogl_framebuffer_draw_rectangle (pass->framebuffer,
|
||||
pass->pipeline,
|
||||
0, 0,
|
||||
cogl_texture_get_width (pass->texture),
|
||||
cogl_texture_get_height (pass->texture));
|
||||
}
|
||||
|
||||
static void
|
||||
clear_blur_pass (BlurPass *pass)
|
||||
{
|
||||
g_clear_pointer (&pass->pipeline, cogl_object_unref);
|
||||
g_clear_pointer (&pass->texture, cogl_object_unref);
|
||||
g_clear_object (&pass->framebuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_blur_new:
|
||||
* @texture: a #CoglTexture
|
||||
* @sigma: blur sigma
|
||||
*
|
||||
* Creates a new #ClutterBlur.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): A newly created #ClutterBlur
|
||||
*/
|
||||
ClutterBlur *
|
||||
clutter_blur_new (CoglTexture *texture,
|
||||
float sigma)
|
||||
{
|
||||
ClutterBlur *blur;
|
||||
unsigned int height;
|
||||
unsigned int width;
|
||||
BlurPass *hpass;
|
||||
BlurPass *vpass;
|
||||
|
||||
g_return_val_if_fail (texture != NULL, NULL);
|
||||
g_return_val_if_fail (sigma >= 0.0, NULL);
|
||||
|
||||
width = cogl_texture_get_width (texture);
|
||||
height = cogl_texture_get_height (texture);
|
||||
|
||||
blur = g_new0 (ClutterBlur, 1);
|
||||
blur->sigma = sigma;
|
||||
blur->source_texture = cogl_object_ref (texture);
|
||||
blur->downscale_factor = calculate_downscale_factor (width, height, sigma);
|
||||
|
||||
if (G_APPROX_VALUE (sigma, 0.0, FLT_EPSILON))
|
||||
goto out;
|
||||
|
||||
vpass = &blur->pass[VERTICAL];
|
||||
hpass = &blur->pass[HORIZONTAL];
|
||||
|
||||
if (!setup_blur_pass (blur, vpass, VERTICAL, texture) ||
|
||||
!setup_blur_pass (blur, hpass, HORIZONTAL, vpass->texture))
|
||||
{
|
||||
clutter_blur_free (blur);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
return g_steal_pointer (&blur);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_blur_apply:
|
||||
* @blur: a #ClutterBlur
|
||||
*
|
||||
* Applies the blur. The resulting texture can be retrieved by
|
||||
* clutter_blur_get_texture().
|
||||
*/
|
||||
void
|
||||
clutter_blur_apply (ClutterBlur *blur)
|
||||
{
|
||||
if (G_APPROX_VALUE (blur->sigma, 0.0, FLT_EPSILON))
|
||||
return;
|
||||
|
||||
apply_blur_pass (&blur->pass[VERTICAL]);
|
||||
apply_blur_pass (&blur->pass[HORIZONTAL]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_blur_get_texture:
|
||||
* @blur: a #ClutterBlur
|
||||
*
|
||||
* Retrieves the texture where the blurred contents are stored. The
|
||||
* contents are undefined until clutter_blur_apply() is called.
|
||||
*
|
||||
* Returns: (transfer none): a #CoglTexture
|
||||
*/
|
||||
CoglTexture *
|
||||
clutter_blur_get_texture (ClutterBlur *blur)
|
||||
{
|
||||
if (G_APPROX_VALUE (blur->sigma, 0.0, FLT_EPSILON))
|
||||
return blur->source_texture;
|
||||
else
|
||||
return blur->pass[HORIZONTAL].texture;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_blur_free:
|
||||
* @blur: A #ClutterBlur
|
||||
*
|
||||
* Frees @blur.
|
||||
*/
|
||||
void
|
||||
clutter_blur_free (ClutterBlur *blur)
|
||||
{
|
||||
g_assert (blur);
|
||||
|
||||
clear_blur_pass (&blur->pass[VERTICAL]);
|
||||
clear_blur_pass (&blur->pass[HORIZONTAL]);
|
||||
cogl_clear_object (&blur->source_texture);
|
||||
g_free (blur);
|
||||
}
|
@ -39,7 +39,7 @@
|
||||
* #ClutterActor:y-expand are set, the available size
|
||||
* - honours the #ClutterActor's #ClutterActor:x-align and #ClutterActor:y-align properties
|
||||
* to fill the available size
|
||||
* - if the #ClutterBoxLayout:homogeneous boolean property is set, then all widgets will
|
||||
* - if the #ClutterBoxLayout:homogeneous boolean propert is set, then all widgets will
|
||||
* get the same size, ignoring expand settings and the preferred sizes
|
||||
*
|
||||
* It is possible to control the spacing between children of a
|
||||
@ -167,10 +167,8 @@ get_preferred_size_for_orientation (ClutterBoxLayout *self,
|
||||
ClutterActor *child;
|
||||
gint n_children = 0;
|
||||
gfloat minimum, natural;
|
||||
float largest_min_size, largest_nat_size;
|
||||
|
||||
minimum = natural = 0;
|
||||
largest_min_size = largest_nat_size = 0;
|
||||
|
||||
clutter_actor_iter_init (&iter, container);
|
||||
while (clutter_actor_iter_next (&iter, &child))
|
||||
@ -185,22 +183,8 @@ get_preferred_size_for_orientation (ClutterBoxLayout *self,
|
||||
get_child_size (child, priv->orientation,
|
||||
for_size, &child_min, &child_nat);
|
||||
|
||||
if (priv->is_homogeneous)
|
||||
{
|
||||
largest_min_size = MAX (largest_min_size, child_min);
|
||||
largest_nat_size = MAX (largest_nat_size, child_nat);
|
||||
}
|
||||
else
|
||||
{
|
||||
minimum += child_min;
|
||||
natural += child_nat;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->is_homogeneous)
|
||||
{
|
||||
minimum = largest_min_size * n_children;
|
||||
natural = largest_nat_size * n_children;
|
||||
minimum += child_min;
|
||||
natural += child_nat;
|
||||
}
|
||||
|
||||
if (n_children > 1)
|
||||
@ -331,8 +315,6 @@ get_preferred_size_for_opposite_orientation (ClutterBoxLayout *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
size -= (nvis_children - 1) * priv->spacing;
|
||||
|
||||
/* Bring children up to size first */
|
||||
if (isnormal (size) || size == 0)
|
||||
{
|
||||
@ -719,7 +701,7 @@ clutter_box_layout_allocate (ClutterLayoutManager *layout,
|
||||
|
||||
if (priv->is_homogeneous)
|
||||
{
|
||||
/* If were homogeneous we still need to run the above loop to get the
|
||||
/* If were homogenous we still need to run the above loop to get the
|
||||
* minimum sizes for children that are not going to fill
|
||||
*/
|
||||
if (priv->orientation == CLUTTER_ORIENTATION_VERTICAL)
|
||||
@ -1218,7 +1200,7 @@ clutter_box_layout_get_homogeneous (ClutterBoxLayout *layout)
|
||||
* @pack_start: %TRUE if the @layout should pack children at the
|
||||
* beginning of the layout
|
||||
*
|
||||
* Sets whether children of @layout should be laid out by appending
|
||||
* Sets whether children of @layout should be layed out by appending
|
||||
* them or by prepending them
|
||||
*
|
||||
* Since: 1.2
|
||||
|
@ -41,6 +41,8 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||
|
||||
#include "clutter-brightness-contrast-effect.h"
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
@ -67,6 +69,9 @@ struct _ClutterBrightnessContrastEffect
|
||||
gint brightness_offset_uniform;
|
||||
gint contrast_uniform;
|
||||
|
||||
gint tex_width;
|
||||
gint tex_height;
|
||||
|
||||
CoglPipeline *pipeline;
|
||||
};
|
||||
|
||||
@ -124,26 +129,16 @@ will_have_no_effect (ClutterBrightnessContrastEffect *self)
|
||||
G_APPROX_VALUE (self->contrast_blue, no_change, FLT_EPSILON));
|
||||
}
|
||||
|
||||
static CoglPipeline *
|
||||
clutter_brightness_contrast_effect_create_pipeline (ClutterOffscreenEffect *effect,
|
||||
CoglTexture *texture)
|
||||
{
|
||||
ClutterBrightnessContrastEffect *self =
|
||||
CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
|
||||
|
||||
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
|
||||
|
||||
return cogl_object_ref (self->pipeline);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
|
||||
ClutterEffectClass *parent_class;
|
||||
|
||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
|
||||
return FALSE;
|
||||
|
||||
if (will_have_no_effect (self))
|
||||
return FALSE;
|
||||
|
||||
@ -162,8 +157,47 @@ clutter_brightness_contrast_effect_pre_paint (ClutterEffect *effect,
|
||||
|
||||
parent_class =
|
||||
CLUTTER_EFFECT_CLASS (clutter_brightness_contrast_effect_parent_class);
|
||||
if (parent_class->pre_paint (effect, paint_context))
|
||||
{
|
||||
ClutterOffscreenEffect *offscreen_effect =
|
||||
CLUTTER_OFFSCREEN_EFFECT (effect);
|
||||
CoglHandle texture;
|
||||
|
||||
return parent_class->pre_paint (effect, node, paint_context);
|
||||
texture = clutter_offscreen_effect_get_texture (offscreen_effect);
|
||||
self->tex_width = cogl_texture_get_width (texture);
|
||||
self->tex_height = cogl_texture_get_height (texture);
|
||||
|
||||
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_brightness_contrast_effect_paint_target (ClutterOffscreenEffect *effect,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect);
|
||||
CoglFramebuffer *framebuffer =
|
||||
clutter_paint_context_get_framebuffer (paint_context);
|
||||
ClutterActor *actor;
|
||||
guint8 paint_opacity;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
|
||||
paint_opacity = clutter_actor_get_paint_opacity (actor);
|
||||
|
||||
cogl_pipeline_set_color4ub (self->pipeline,
|
||||
paint_opacity,
|
||||
paint_opacity,
|
||||
paint_opacity,
|
||||
paint_opacity);
|
||||
|
||||
cogl_framebuffer_draw_rectangle (framebuffer,
|
||||
self->pipeline,
|
||||
0, 0,
|
||||
self->tex_width, self->tex_height);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -263,7 +297,7 @@ clutter_brightness_contrast_effect_class_init (ClutterBrightnessContrastEffectCl
|
||||
ClutterOffscreenEffectClass *offscreen_class;
|
||||
|
||||
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
||||
offscreen_class->create_pipeline = clutter_brightness_contrast_effect_create_pipeline;
|
||||
offscreen_class->paint_target = clutter_brightness_contrast_effect_paint_target;
|
||||
|
||||
effect_class->pre_paint = clutter_brightness_contrast_effect_pre_paint;
|
||||
|
||||
|
@ -4,5 +4,11 @@
|
||||
/* List of Cogl drivers */
|
||||
#mesondefine CLUTTER_DRIVERS
|
||||
|
||||
/* Have evdev support for input handling */
|
||||
#mesondefine HAVE_EVDEV
|
||||
|
||||
/* Building with libwacom for advanced tablet management */
|
||||
#mesondefine HAVE_LIBWACOM
|
||||
|
||||
/* Supports PangoFt2 */
|
||||
#mesondefine HAVE_PANGO_FT2
|
||||
|
@ -50,6 +50,8 @@
|
||||
|
||||
#include "clutter-canvas.h"
|
||||
|
||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||
|
||||
#include "clutter-actor-private.h"
|
||||
#include "clutter-backend.h"
|
||||
#include "clutter-cairo.h"
|
||||
|
@ -105,6 +105,8 @@ struct _ClutterClickActionPrivate
|
||||
{
|
||||
ClutterActor *stage;
|
||||
|
||||
gulong event_id;
|
||||
gulong capture_id;
|
||||
guint long_press_id;
|
||||
|
||||
gint long_press_threshold;
|
||||
@ -112,7 +114,7 @@ struct _ClutterClickActionPrivate
|
||||
gint drag_threshold;
|
||||
|
||||
guint press_button;
|
||||
ClutterInputDevice *press_device;
|
||||
gint press_device_id;
|
||||
ClutterEventSequence *press_sequence;
|
||||
ClutterModifierType modifier_state;
|
||||
gfloat press_x;
|
||||
@ -148,6 +150,11 @@ 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)
|
||||
@ -198,6 +205,8 @@ click_action_emit_long_press (gpointer data)
|
||||
CLUTTER_LONG_PRESS_ACTIVATE,
|
||||
&result);
|
||||
|
||||
g_clear_signal_handler (&priv->capture_id, priv->stage);
|
||||
|
||||
click_action_set_pressed (action, FALSE);
|
||||
click_action_set_held (action, FALSE);
|
||||
|
||||
@ -263,51 +272,26 @@ 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));
|
||||
clutter_click_action_get_instance_private (action);
|
||||
gboolean has_button = TRUE;
|
||||
ClutterModifierType modifier_state;
|
||||
|
||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if (priv->press_sequence != NULL &&
|
||||
clutter_event_get_event_sequence (event) != priv->press_sequence)
|
||||
{
|
||||
click_action_set_held (click_action, FALSE);
|
||||
click_action_cancel_long_press (click_action);
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
switch (clutter_event_type (event))
|
||||
{
|
||||
case CLUTTER_TOUCH_BEGIN:
|
||||
has_button = FALSE;
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
if (has_button && clutter_event_get_click_count (event) != 1)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if (priv->is_held)
|
||||
return CLUTTER_EVENT_STOP;
|
||||
|
||||
@ -315,7 +299,7 @@ clutter_click_action_handle_event (ClutterAction *action,
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
priv->press_button = has_button ? clutter_event_get_button (event) : 0;
|
||||
priv->press_device = clutter_event_get_device (event);
|
||||
priv->press_device_id = clutter_event_get_device_id (event);
|
||||
priv->press_sequence = clutter_event_get_event_sequence (event);
|
||||
priv->modifier_state = clutter_event_get_state (event);
|
||||
clutter_event_get_coords (event, &priv->press_x, &priv->press_y);
|
||||
@ -334,22 +318,48 @@ clutter_click_action_handle_event (ClutterAction *action,
|
||||
if (priv->stage == NULL)
|
||||
priv->stage = clutter_actor_get_stage (actor);
|
||||
|
||||
click_action_set_pressed (click_action, TRUE);
|
||||
click_action_set_held (click_action, TRUE);
|
||||
click_action_query_long_press (click_action);
|
||||
priv->capture_id = g_signal_connect_after (priv->stage, "captured-event",
|
||||
G_CALLBACK (on_captured_event),
|
||||
action);
|
||||
|
||||
click_action_set_pressed (action, TRUE);
|
||||
click_action_set_held (action, TRUE);
|
||||
click_action_query_long_press (action);
|
||||
break;
|
||||
|
||||
case CLUTTER_ENTER:
|
||||
click_action_set_pressed (click_action, priv->is_held);
|
||||
click_action_set_pressed (action, priv->is_held);
|
||||
break;
|
||||
|
||||
case CLUTTER_LEAVE:
|
||||
click_action_set_pressed (click_action, priv->is_held);
|
||||
click_action_cancel_long_press (click_action);
|
||||
click_action_set_pressed (action, priv->is_held);
|
||||
click_action_cancel_long_press (action);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_captured_event (ClutterActor *stage,
|
||||
ClutterEvent *event,
|
||||
ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
ClutterActor *actor;
|
||||
ClutterModifierType modifier_state;
|
||||
gboolean has_button = TRUE;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
||||
|
||||
switch (clutter_event_type (event))
|
||||
{
|
||||
case CLUTTER_TOUCH_CANCEL:
|
||||
clutter_click_action_release (click_action);
|
||||
clutter_click_action_release (action);
|
||||
break;
|
||||
|
||||
case CLUTTER_TOUCH_END:
|
||||
@ -359,12 +369,16 @@ clutter_click_action_handle_event (ClutterAction *action,
|
||||
return CLUTTER_EVENT_STOP;
|
||||
|
||||
if ((has_button && clutter_event_get_button (event) != priv->press_button) ||
|
||||
clutter_event_get_device (event) != priv->press_device ||
|
||||
(has_button && clutter_event_get_click_count (event) != 1) ||
|
||||
clutter_event_get_device_id (event) != priv->press_device_id ||
|
||||
clutter_event_get_event_sequence (event) != priv->press_sequence)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
click_action_set_held (click_action, FALSE);
|
||||
click_action_cancel_long_press (click_action);
|
||||
click_action_set_held (action, FALSE);
|
||||
click_action_cancel_long_press (action);
|
||||
|
||||
/* disconnect the capture */
|
||||
g_clear_signal_handler (&priv->capture_id, priv->stage);
|
||||
|
||||
g_clear_handle_id (&priv->long_press_id, g_source_remove);
|
||||
|
||||
@ -387,24 +401,31 @@ clutter_click_action_handle_event (ClutterAction *action,
|
||||
if (modifier_state != priv->modifier_state)
|
||||
priv->modifier_state = 0;
|
||||
|
||||
click_action_set_pressed (click_action, FALSE);
|
||||
|
||||
if (event_within_drag_threshold (click_action, event))
|
||||
g_signal_emit (click_action, click_signals[CLICKED], 0, actor);
|
||||
click_action_set_pressed (action, FALSE);
|
||||
g_signal_emit (action, click_signals[CLICKED], 0, actor);
|
||||
break;
|
||||
|
||||
case CLUTTER_MOTION:
|
||||
case CLUTTER_TOUCH_UPDATE:
|
||||
{
|
||||
if (clutter_event_get_device (event) != priv->press_device ||
|
||||
gfloat motion_x, motion_y;
|
||||
gfloat delta_x, delta_y;
|
||||
|
||||
if (clutter_event_get_device_id (event) != priv->press_device_id ||
|
||||
clutter_event_get_event_sequence (event) != priv->press_sequence)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if (!priv->is_held)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if (!event_within_drag_threshold (click_action, event))
|
||||
clutter_click_action_release (click_action);
|
||||
clutter_event_get_coords (event, &motion_x, &motion_y);
|
||||
|
||||
delta_x = ABS (motion_x - priv->press_x);
|
||||
delta_y = ABS (motion_y - priv->press_y);
|
||||
|
||||
if (delta_x > priv->drag_threshold ||
|
||||
delta_y > priv->drag_threshold)
|
||||
click_action_cancel_long_press (action);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -412,7 +433,7 @@ clutter_click_action_handle_event (ClutterAction *action,
|
||||
break;
|
||||
}
|
||||
|
||||
return priv->is_held ? CLUTTER_EVENT_STOP : CLUTTER_EVENT_PROPAGATE;
|
||||
return CLUTTER_EVENT_STOP;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -423,11 +444,35 @@ clutter_click_action_set_actor (ClutterActorMeta *meta,
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
|
||||
if (priv->event_id != 0)
|
||||
{
|
||||
ClutterActor *old_actor = clutter_actor_meta_get_actor (meta);
|
||||
|
||||
if (old_actor != NULL)
|
||||
g_clear_signal_handler (&priv->event_id, old_actor);
|
||||
|
||||
priv->event_id = 0;
|
||||
}
|
||||
|
||||
if (priv->capture_id != 0)
|
||||
{
|
||||
if (priv->stage != NULL)
|
||||
g_clear_signal_handler (&priv->capture_id, priv->stage);
|
||||
|
||||
priv->capture_id = 0;
|
||||
priv->stage = NULL;
|
||||
}
|
||||
|
||||
g_clear_handle_id (&priv->long_press_id, g_source_remove);
|
||||
|
||||
click_action_set_pressed (action, FALSE);
|
||||
click_action_set_held (action, FALSE);
|
||||
|
||||
if (actor != NULL)
|
||||
priv->event_id = g_signal_connect (actor, "event",
|
||||
G_CALLBACK (on_event),
|
||||
action);
|
||||
|
||||
CLUTTER_ACTOR_META_CLASS (clutter_click_action_parent_class)->set_actor (meta, actor);
|
||||
}
|
||||
|
||||
@ -509,19 +554,22 @@ clutter_click_action_dispose (GObject *gobject)
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
|
||||
|
||||
g_clear_signal_handler (&priv->event_id,
|
||||
clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (gobject)));
|
||||
|
||||
g_clear_signal_handler (&priv->capture_id, priv->stage);
|
||||
|
||||
g_clear_handle_id (&priv->long_press_id, g_source_remove);
|
||||
|
||||
G_OBJECT_CLASS (clutter_click_action_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
clutter_click_action_class_init (ClutterClickActionClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
|
||||
ClutterActionClass *action_class = CLUTTER_ACTION_CLASS (klass);
|
||||
|
||||
action_class->handle_event = clutter_click_action_handle_event;
|
||||
|
||||
meta_class->set_actor = clutter_click_action_set_actor;
|
||||
meta_class->set_enabled = clutter_click_action_set_enabled;
|
||||
@ -711,6 +759,9 @@ clutter_click_action_release (ClutterClickAction *action)
|
||||
if (!priv->is_held)
|
||||
return;
|
||||
|
||||
/* disconnect the capture */
|
||||
g_clear_signal_handler (&priv->capture_id, priv->stage);
|
||||
|
||||
click_action_cancel_long_press (action);
|
||||
click_action_set_held (action, FALSE);
|
||||
click_action_set_pressed (action, FALSE);
|
||||
|
@ -39,6 +39,7 @@
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||
#include "clutter-actor-private.h"
|
||||
#include "clutter-clone.h"
|
||||
#include "clutter-debug.h"
|
||||
@ -51,8 +52,6 @@
|
||||
struct _ClutterClonePrivate
|
||||
{
|
||||
ClutterActor *clone_source;
|
||||
float x_scale, y_scale;
|
||||
|
||||
gulong source_destroy_id;
|
||||
};
|
||||
|
||||
@ -120,17 +119,36 @@ clutter_clone_get_preferred_height (ClutterActor *self,
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_clone_apply_transform (ClutterActor *self,
|
||||
graphene_matrix_t *matrix)
|
||||
clutter_clone_apply_transform (ClutterActor *self, CoglMatrix *matrix)
|
||||
{
|
||||
ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
|
||||
ClutterActorBox box, source_box;
|
||||
gfloat x_scale, y_scale;
|
||||
|
||||
|
||||
if (priv->clone_source)
|
||||
graphene_matrix_scale (matrix, priv->x_scale, priv->y_scale, 1.f);
|
||||
|
||||
/* First chain up and apply all the standard ClutterActor
|
||||
* transformations... */
|
||||
CLUTTER_ACTOR_CLASS (clutter_clone_parent_class)->apply_transform (self,
|
||||
matrix);
|
||||
|
||||
/* if we don't have a source, nothing else to do */
|
||||
if (priv->clone_source == NULL)
|
||||
return;
|
||||
|
||||
/* get our allocated size */
|
||||
clutter_actor_get_allocation_box (self, &box);
|
||||
|
||||
/* and get the allocated size of the source */
|
||||
clutter_actor_get_allocation_box (priv->clone_source, &source_box);
|
||||
|
||||
/* We need to scale what the clone-source actor paints to fill our own
|
||||
* allocation...
|
||||
*/
|
||||
x_scale = clutter_actor_box_get_width (&box)
|
||||
/ clutter_actor_box_get_width (&source_box);
|
||||
y_scale = clutter_actor_box_get_height (&box)
|
||||
/ clutter_actor_box_get_height (&source_box);
|
||||
|
||||
cogl_matrix_scale (matrix, x_scale, y_scale, x_scale);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -195,7 +213,7 @@ clutter_clone_get_paint_volume (ClutterActor *actor,
|
||||
if (priv->clone_source == NULL)
|
||||
return TRUE;
|
||||
|
||||
/* query the volume of the source actor and simply masquerade it as
|
||||
/* query the volume of the source actor and simply masquarade it as
|
||||
* the clones volume... */
|
||||
source_volume = clutter_actor_get_paint_volume (priv->clone_source);
|
||||
if (source_volume == NULL)
|
||||
@ -226,8 +244,6 @@ clutter_clone_allocate (ClutterActor *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);
|
||||
@ -241,31 +257,7 @@ clutter_clone_allocate (ClutterActor *self,
|
||||
*/
|
||||
if (clutter_actor_get_parent (priv->clone_source) != NULL &&
|
||||
!clutter_actor_has_allocation (priv->clone_source))
|
||||
{
|
||||
float x = 0.f;
|
||||
float y = 0.f;
|
||||
|
||||
clutter_actor_get_fixed_position (priv->clone_source, &x, &y);
|
||||
clutter_actor_allocate_preferred_size (priv->clone_source, x, y);
|
||||
}
|
||||
|
||||
clutter_actor_get_allocation_box (priv->clone_source, &source_box);
|
||||
|
||||
/* We need to scale what the clone-source actor paints to fill our own
|
||||
* allocation...
|
||||
*/
|
||||
x_scale = clutter_actor_box_get_width (box)
|
||||
/ clutter_actor_box_get_width (&source_box);
|
||||
y_scale = clutter_actor_box_get_height (box)
|
||||
/ clutter_actor_box_get_height (&source_box);
|
||||
|
||||
if (!G_APPROX_VALUE (priv->x_scale, x_scale, FLT_EPSILON) ||
|
||||
!G_APPROX_VALUE (priv->y_scale, y_scale, FLT_EPSILON))
|
||||
{
|
||||
priv->x_scale = x_scale;
|
||||
priv->y_scale = y_scale;
|
||||
clutter_actor_invalidate_transform (CLUTTER_ACTOR (self));
|
||||
}
|
||||
clutter_actor_allocate_preferred_size (priv->clone_source);
|
||||
|
||||
#if 0
|
||||
/* XXX - this is wrong: ClutterClone cannot clone unparented
|
||||
@ -372,9 +364,6 @@ static void
|
||||
clutter_clone_init (ClutterClone *self)
|
||||
{
|
||||
self->priv = clutter_clone_get_instance_private (self);
|
||||
|
||||
self->priv->x_scale = 1.f;
|
||||
self->priv->y_scale = 1.f;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -611,7 +611,7 @@ parse_hsla (ClutterColor *color,
|
||||
/**
|
||||
* clutter_color_from_string:
|
||||
* @color: (out caller-allocates): return location for a #ClutterColor
|
||||
* @str: a string specifying a color
|
||||
* @str: a string specifiying a color
|
||||
*
|
||||
* Parses a string definition of a color, filling the #ClutterColor.red,
|
||||
* #ClutterColor.green, #ClutterColor.blue and #ClutterColor.alpha fields
|
||||
@ -911,7 +911,7 @@ ClutterColor *
|
||||
clutter_color_copy (const ClutterColor *color)
|
||||
{
|
||||
if (G_LIKELY (color != NULL))
|
||||
return g_memdup2 (color, sizeof (ClutterColor));
|
||||
return g_slice_dup (ClutterColor, color);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -928,7 +928,7 @@ void
|
||||
clutter_color_free (ClutterColor *color)
|
||||
{
|
||||
if (G_LIKELY (color != NULL))
|
||||
g_free (color);
|
||||
g_slice_free (ClutterColor, color);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -977,7 +977,7 @@ clutter_color_new (guint8 red,
|
||||
ClutterColor *
|
||||
clutter_color_alloc (void)
|
||||
{
|
||||
return g_new0 (ClutterColor, 1);
|
||||
return g_slice_new0 (ClutterColor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -39,6 +39,8 @@
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||
|
||||
#include "clutter-colorize-effect.h"
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
@ -57,6 +59,9 @@ struct _ClutterColorizeEffect
|
||||
|
||||
gint tint_uniform;
|
||||
|
||||
gint tex_width;
|
||||
gint tex_height;
|
||||
|
||||
CoglPipeline *pipeline;
|
||||
};
|
||||
|
||||
@ -99,24 +104,16 @@ G_DEFINE_TYPE (ClutterColorizeEffect,
|
||||
clutter_colorize_effect,
|
||||
CLUTTER_TYPE_OFFSCREEN_EFFECT);
|
||||
|
||||
static CoglPipeline *
|
||||
clutter_colorize_effect_create_pipeline (ClutterOffscreenEffect *effect,
|
||||
CoglTexture *texture)
|
||||
{
|
||||
ClutterColorizeEffect *colorize_effect = CLUTTER_COLORIZE_EFFECT (effect);
|
||||
|
||||
cogl_pipeline_set_layer_texture (colorize_effect->pipeline, 0, texture);
|
||||
|
||||
return cogl_object_ref (colorize_effect->pipeline);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_colorize_effect_pre_paint (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect);
|
||||
ClutterEffectClass *parent_class;
|
||||
|
||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
|
||||
return FALSE;
|
||||
|
||||
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
|
||||
{
|
||||
/* if we don't have support for GLSL shaders then we
|
||||
@ -130,7 +127,47 @@ clutter_colorize_effect_pre_paint (ClutterEffect *effect,
|
||||
}
|
||||
|
||||
parent_class = CLUTTER_EFFECT_CLASS (clutter_colorize_effect_parent_class);
|
||||
return parent_class->pre_paint (effect, node, paint_context);
|
||||
if (parent_class->pre_paint (effect, paint_context))
|
||||
{
|
||||
ClutterOffscreenEffect *offscreen_effect =
|
||||
CLUTTER_OFFSCREEN_EFFECT (effect);
|
||||
CoglHandle texture;
|
||||
|
||||
texture = clutter_offscreen_effect_get_texture (offscreen_effect);
|
||||
self->tex_width = cogl_texture_get_width (texture);
|
||||
self->tex_height = cogl_texture_get_height (texture);
|
||||
|
||||
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_colorize_effect_paint_target (ClutterOffscreenEffect *effect,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect);
|
||||
CoglFramebuffer *framebuffer =
|
||||
clutter_paint_context_get_framebuffer (paint_context);
|
||||
ClutterActor *actor;
|
||||
guint8 paint_opacity;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
|
||||
paint_opacity = clutter_actor_get_paint_opacity (actor);
|
||||
|
||||
cogl_pipeline_set_color4ub (self->pipeline,
|
||||
paint_opacity,
|
||||
paint_opacity,
|
||||
paint_opacity,
|
||||
paint_opacity);
|
||||
|
||||
cogl_framebuffer_draw_rectangle (framebuffer,
|
||||
self->pipeline,
|
||||
0, 0,
|
||||
self->tex_width, self->tex_height);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -196,7 +233,7 @@ clutter_colorize_effect_class_init (ClutterColorizeEffectClass *klass)
|
||||
ClutterOffscreenEffectClass *offscreen_class;
|
||||
|
||||
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
||||
offscreen_class->create_pipeline = clutter_colorize_effect_create_pipeline;
|
||||
offscreen_class->paint_target = clutter_colorize_effect_paint_target;
|
||||
|
||||
effect_class->pre_paint = clutter_colorize_effect_pre_paint;
|
||||
|
||||
|
22
clutter/clutter/clutter-config.h.in
Normal file
22
clutter/clutter/clutter-config.h.in
Normal file
@ -0,0 +1,22 @@
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __CLUTTER_CONFIG_H__
|
||||
#define __CLUTTER_CONFIG_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#mesondefine CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
|
||||
#mesondefine CLUTTER_WINDOWING_X11
|
||||
#mesondefine CLUTTER_INPUT_X11
|
||||
#mesondefine CLUTTER_WINDOWING_GLX
|
||||
#mesondefine CLUTTER_WINDOWING_EGL
|
||||
#mesondefine CLUTTER_INPUT_EVDEV
|
||||
#mesondefine CLUTTER_INPUT_NULL
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_CONFIG_H__ */
|
@ -119,6 +119,31 @@ container_real_remove (ClutterContainer *container,
|
||||
clutter_actor_remove_child (CLUTTER_ACTOR (container), actor);
|
||||
}
|
||||
|
||||
static void
|
||||
container_real_raise (ClutterContainer *container,
|
||||
ClutterActor *child,
|
||||
ClutterActor *sibling)
|
||||
{
|
||||
ClutterActor *self = CLUTTER_ACTOR (container);
|
||||
|
||||
clutter_actor_set_child_above_sibling (self, child, sibling);
|
||||
}
|
||||
|
||||
static void
|
||||
container_real_lower (ClutterContainer *container,
|
||||
ClutterActor *child,
|
||||
ClutterActor *sibling)
|
||||
{
|
||||
ClutterActor *self = CLUTTER_ACTOR (container);
|
||||
|
||||
clutter_actor_set_child_below_sibling (self, child, sibling);
|
||||
}
|
||||
|
||||
static void
|
||||
container_real_sort_depth_order (ClutterContainer *container)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_container_default_init (ClutterContainerInterface *iface)
|
||||
{
|
||||
@ -188,6 +213,9 @@ clutter_container_default_init (ClutterContainerInterface *iface)
|
||||
|
||||
iface->add = container_real_add;
|
||||
iface->remove = container_real_remove;
|
||||
iface->raise = container_real_raise;
|
||||
iface->lower = container_real_lower;
|
||||
iface->sort_depth_order = container_real_sort_depth_order;
|
||||
|
||||
iface->child_meta_type = G_TYPE_INVALID;
|
||||
iface->create_child_meta = create_child_meta;
|
||||
@ -420,6 +448,202 @@ clutter_container_remove_actor (ClutterContainer *container,
|
||||
container_remove_actor (container, actor);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_container_get_children:
|
||||
* @container: a #ClutterContainer
|
||||
*
|
||||
* Retrieves all the children of @container.
|
||||
*
|
||||
* Return value: (element-type Clutter.Actor) (transfer container): a list
|
||||
* of #ClutterActor<!-- -->s. Use g_list_free() on the returned
|
||||
* list when done.
|
||||
*
|
||||
* Since: 0.4
|
||||
*
|
||||
* Deprecated: 1.10: Use clutter_actor_get_children() instead.
|
||||
*/
|
||||
GList *
|
||||
clutter_container_get_children (ClutterContainer *container)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_CONTAINER (container), NULL);
|
||||
|
||||
return clutter_actor_get_children (CLUTTER_ACTOR (container));
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_container_raise_child: (virtual raise)
|
||||
* @container: a #ClutterContainer
|
||||
* @actor: the actor to raise
|
||||
* @sibling: (allow-none): the sibling to raise to, or %NULL to raise
|
||||
* to the top
|
||||
*
|
||||
* Raises @actor to @sibling level, in the depth ordering.
|
||||
*
|
||||
* This function calls the #ClutterContainerIface.raise() virtual function,
|
||||
* which has been deprecated. The default implementation will call
|
||||
* clutter_actor_set_child_above_sibling().
|
||||
*
|
||||
* Since: 0.6
|
||||
*
|
||||
* Deprecated: 1.10: Use clutter_actor_set_child_above_sibling() instead.
|
||||
*/
|
||||
void
|
||||
clutter_container_raise_child (ClutterContainer *container,
|
||||
ClutterActor *actor,
|
||||
ClutterActor *sibling)
|
||||
{
|
||||
ClutterContainerIface *iface;
|
||||
ClutterActor *self;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||
g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling));
|
||||
|
||||
if (actor == sibling)
|
||||
return;
|
||||
|
||||
self = CLUTTER_ACTOR (container);
|
||||
|
||||
if (clutter_actor_get_parent (actor) != self)
|
||||
{
|
||||
g_warning ("Actor of type '%s' is not a child of the container "
|
||||
"of type '%s'",
|
||||
g_type_name (G_OBJECT_TYPE (actor)),
|
||||
g_type_name (G_OBJECT_TYPE (container)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (sibling != NULL &&
|
||||
clutter_actor_get_parent (sibling) != self)
|
||||
{
|
||||
g_warning ("Actor of type '%s' is not a child of the container "
|
||||
"of type '%s'",
|
||||
g_type_name (G_OBJECT_TYPE (sibling)),
|
||||
g_type_name (G_OBJECT_TYPE (container)));
|
||||
return;
|
||||
}
|
||||
|
||||
iface = CLUTTER_CONTAINER_GET_IFACE (container);
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
if (G_UNLIKELY (_clutter_diagnostic_enabled ()))
|
||||
{
|
||||
if (iface->raise != container_real_raise)
|
||||
_clutter_diagnostic_message ("The ClutterContainer::raise() "
|
||||
"virtual function has been deprecated "
|
||||
"and it should not be overridden by "
|
||||
"newly written code");
|
||||
}
|
||||
#endif /* CLUTTER_ENABLE_DEBUG */
|
||||
|
||||
iface->raise (container, actor, sibling);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_container_lower_child: (virtual lower)
|
||||
* @container: a #ClutterContainer
|
||||
* @actor: the actor to raise
|
||||
* @sibling: (allow-none): the sibling to lower to, or %NULL to lower
|
||||
* to the bottom
|
||||
*
|
||||
* Lowers @actor to @sibling level, in the depth ordering.
|
||||
*
|
||||
* This function calls the #ClutterContainerIface.lower() virtual function,
|
||||
* which has been deprecated. The default implementation will call
|
||||
* clutter_actor_set_child_below_sibling().
|
||||
*
|
||||
* Since: 0.6
|
||||
*
|
||||
* Deprecated: 1.10: Use clutter_actor_set_child_below_sibling() instead.
|
||||
*/
|
||||
void
|
||||
clutter_container_lower_child (ClutterContainer *container,
|
||||
ClutterActor *actor,
|
||||
ClutterActor *sibling)
|
||||
{
|
||||
ClutterContainerIface *iface;
|
||||
ClutterActor *self;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (actor));
|
||||
g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling));
|
||||
|
||||
if (actor == sibling)
|
||||
return;
|
||||
|
||||
self = CLUTTER_ACTOR (container);
|
||||
|
||||
if (clutter_actor_get_parent (actor) != self)
|
||||
{
|
||||
g_warning ("Actor of type '%s' is not a child of the container "
|
||||
"of type '%s'",
|
||||
g_type_name (G_OBJECT_TYPE (actor)),
|
||||
g_type_name (G_OBJECT_TYPE (container)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (sibling != NULL&&
|
||||
clutter_actor_get_parent (sibling) != self)
|
||||
{
|
||||
g_warning ("Actor of type '%s' is not a child of the container "
|
||||
"of type '%s'",
|
||||
g_type_name (G_OBJECT_TYPE (sibling)),
|
||||
g_type_name (G_OBJECT_TYPE (container)));
|
||||
return;
|
||||
}
|
||||
|
||||
iface = CLUTTER_CONTAINER_GET_IFACE (container);
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
if (G_UNLIKELY (_clutter_diagnostic_enabled ()))
|
||||
{
|
||||
if (iface->lower != container_real_lower)
|
||||
_clutter_diagnostic_message ("The ClutterContainer::lower() "
|
||||
"virtual function has been deprecated "
|
||||
"and it should not be overridden by "
|
||||
"newly written code");
|
||||
}
|
||||
#endif /* CLUTTER_ENABLE_DEBUG */
|
||||
|
||||
iface->lower (container, actor, sibling);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_container_sort_depth_order:
|
||||
* @container: a #ClutterContainer
|
||||
*
|
||||
* Sorts a container's children using their depth. This function should not
|
||||
* be normally used by applications.
|
||||
*
|
||||
* Since: 0.6
|
||||
*
|
||||
* Deprecated: 1.10: The #ClutterContainerIface.sort_depth_order() virtual
|
||||
* function should not be used any more; the default implementation in
|
||||
* #ClutterContainer does not do anything.
|
||||
*/
|
||||
void
|
||||
clutter_container_sort_depth_order (ClutterContainer *container)
|
||||
{
|
||||
ClutterContainerIface *iface;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_CONTAINER (container));
|
||||
|
||||
iface = CLUTTER_CONTAINER_GET_IFACE (container);
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
if (G_UNLIKELY (_clutter_diagnostic_enabled ()))
|
||||
{
|
||||
if (iface->sort_depth_order != container_real_sort_depth_order)
|
||||
_clutter_diagnostic_message ("The ClutterContainer::sort_depth_order() "
|
||||
"virtual function has been deprecated "
|
||||
"and it should not be overridden by "
|
||||
"newly written code");
|
||||
}
|
||||
#endif /* CLUTTER_ENABLE_DEBUG */
|
||||
|
||||
iface->sort_depth_order (container);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_container_find_child_by_name:
|
||||
* @container: a #ClutterContainer
|
||||
@ -444,7 +668,7 @@ clutter_container_find_child_by_name (ClutterContainer *container,
|
||||
g_return_val_if_fail (CLUTTER_IS_CONTAINER (container), NULL);
|
||||
g_return_val_if_fail (child_name != NULL, NULL);
|
||||
|
||||
children = clutter_actor_get_children (CLUTTER_ACTOR (container));
|
||||
children = clutter_container_get_children (container);
|
||||
|
||||
for (iter = children; iter; iter = g_list_next (iter))
|
||||
{
|
||||
|
@ -59,6 +59,13 @@ typedef struct _ClutterContainerIface ClutterContainerIface;
|
||||
* function is deprecated, and it should not be overridden.
|
||||
* @remove: virtual function for removing an actor from the container. This
|
||||
* virtual function is deprecated, and it should not be overridden.
|
||||
* @raise: virtual function for raising a child. This virtual function is
|
||||
* deprecated and it should not be overridden.
|
||||
* @lower: virtual function for lowering a child. This virtual function is
|
||||
* deprecated and it should not be overridden.
|
||||
* @sort_depth_order: virtual function for sorting the children of a
|
||||
* container depending on their depth. This virtual function is deprecated
|
||||
* and it should not be overridden.
|
||||
* @child_meta_type: The GType used for storing auxiliary information about
|
||||
* each of the containers children.
|
||||
* @create_child_meta: virtual function that gets called for each added
|
||||
@ -67,7 +74,7 @@ typedef struct _ClutterContainerIface ClutterContainerIface;
|
||||
* fields in the instance and add the record to a data structure for
|
||||
* subsequent access for #ClutterContainerIface::get_child_meta
|
||||
* @destroy_child_meta: virtual function that gets called when a child is
|
||||
* removed; it should release all resources held by the record
|
||||
* removed; it shuld release all resources held by the record
|
||||
* @get_child_meta: return the record for a container child
|
||||
* @actor_added: class handler for #ClutterContainer::actor-added
|
||||
* @actor_removed: class handler for #ClutterContainer::actor-removed
|
||||
@ -90,6 +97,15 @@ struct _ClutterContainerIface
|
||||
void (* remove) (ClutterContainer *container,
|
||||
ClutterActor *actor);
|
||||
|
||||
/* child stacking */
|
||||
void (* raise) (ClutterContainer *container,
|
||||
ClutterActor *actor,
|
||||
ClutterActor *sibling);
|
||||
void (* lower) (ClutterContainer *container,
|
||||
ClutterActor *actor,
|
||||
ClutterActor *sibling);
|
||||
void (* sort_depth_order) (ClutterContainer *container);
|
||||
|
||||
/* ClutterChildMeta management */
|
||||
GType child_meta_type;
|
||||
void (* create_child_meta) (ClutterContainer *container,
|
||||
|
@ -322,8 +322,8 @@ _clutter_content_paint_content (ClutterContent *content,
|
||||
/**
|
||||
* clutter_content_get_preferred_size:
|
||||
* @content: a #ClutterContent
|
||||
* @width: (out) (optional): return location for the natural width of the content
|
||||
* @height: (out) (optional): return location for the natural height of the content
|
||||
* @width: (out): return location for the natural width of the content
|
||||
* @height: (out): return location for the natural height of the content
|
||||
*
|
||||
* Retrieves the natural size of the @content, if any.
|
||||
*
|
||||
|
@ -22,28 +22,20 @@
|
||||
#include <cairo.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "clutter-macros.h"
|
||||
|
||||
typedef struct _ClutterDamageHistory ClutterDamageHistory;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterDamageHistory * clutter_damage_history_new (void);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_damage_history_free (ClutterDamageHistory *history);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_damage_history_is_age_valid (ClutterDamageHistory *history,
|
||||
int age);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_damage_history_record (ClutterDamageHistory *history,
|
||||
const cairo_region_t *damage);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_damage_history_step (ClutterDamageHistory *history);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
const cairo_region_t * clutter_damage_history_lookup (ClutterDamageHistory *history,
|
||||
int age);
|
||||
|
||||
|
@ -41,7 +41,6 @@ G_BEGIN_DECLS
|
||||
extern guint clutter_debug_flags;
|
||||
extern guint clutter_pick_debug_flags;
|
||||
extern guint clutter_paint_debug_flags;
|
||||
extern int clutter_max_render_time_constant_us;
|
||||
|
||||
void _clutter_debug_messagev (const char *format,
|
||||
va_list var_args) G_GNUC_PRINTF (1, 0);
|
||||
|
@ -53,16 +53,14 @@
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||
#include "clutter-deform-effect.h"
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include "clutter-color.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-enum-types.h"
|
||||
#include "clutter-offscreen-effect-private.h"
|
||||
#include "clutter-paint-node.h"
|
||||
#include "clutter-paint-nodes.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
#define DEFAULT_N_TILES 32
|
||||
@ -168,16 +166,19 @@ clutter_deform_effect_set_actor (ClutterActorMeta *meta,
|
||||
|
||||
static void
|
||||
clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
ClutterDeformEffect *self= CLUTTER_DEFORM_EFFECT (effect);
|
||||
ClutterDeformEffectPrivate *priv = self->priv;
|
||||
CoglHandle material;
|
||||
CoglPipeline *pipeline;
|
||||
CoglDepthState depth_state;
|
||||
CoglFramebuffer *fb =
|
||||
clutter_paint_context_get_framebuffer (paint_context);
|
||||
|
||||
if (priv->is_dirty)
|
||||
{
|
||||
graphene_rect_t rect;
|
||||
gboolean mapped_buffer;
|
||||
CoglVertexP3T2C4 *verts;
|
||||
ClutterActor *actor;
|
||||
@ -191,7 +192,12 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect,
|
||||
/* if we don't have a target size, fall back to the actor's
|
||||
* allocation, though wrong it might be
|
||||
*/
|
||||
if (!clutter_offscreen_effect_get_target_size (effect, &width, &height))
|
||||
if (clutter_offscreen_effect_get_target_rect (effect, &rect))
|
||||
{
|
||||
width = graphene_rect_get_width (&rect);
|
||||
height = graphene_rect_get_height (&rect);
|
||||
}
|
||||
else
|
||||
clutter_actor_get_size (actor, &width, &height);
|
||||
|
||||
/* XXX ideally, the sub-classes should tell us what they
|
||||
@ -271,7 +277,8 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect,
|
||||
priv->is_dirty = FALSE;
|
||||
}
|
||||
|
||||
pipeline = clutter_offscreen_effect_get_pipeline (effect);
|
||||
material = clutter_offscreen_effect_get_target (effect);
|
||||
pipeline = COGL_PIPELINE (material);
|
||||
|
||||
/* enable depth testing */
|
||||
cogl_depth_state_init (&depth_state);
|
||||
@ -285,22 +292,12 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect,
|
||||
COGL_PIPELINE_CULL_FACE_MODE_BACK);
|
||||
|
||||
/* draw the front */
|
||||
if (pipeline != NULL)
|
||||
{
|
||||
ClutterPaintNode *front_node;
|
||||
|
||||
front_node = clutter_pipeline_node_new (pipeline);
|
||||
clutter_paint_node_set_static_name (front_node,
|
||||
"ClutterDeformEffect (front)");
|
||||
clutter_paint_node_add_child (node, front_node);
|
||||
clutter_paint_node_add_primitive (front_node, priv->primitive);
|
||||
clutter_paint_node_unref (front_node);
|
||||
}
|
||||
if (material != NULL)
|
||||
cogl_framebuffer_draw_primitive (fb, pipeline, priv->primitive);
|
||||
|
||||
/* draw the back */
|
||||
if (priv->back_pipeline != NULL)
|
||||
{
|
||||
ClutterPaintNode *back_node;
|
||||
CoglPipeline *back_pipeline;
|
||||
|
||||
/* We probably shouldn't be modifying the user's material so
|
||||
@ -310,30 +307,20 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect,
|
||||
cogl_pipeline_set_cull_face_mode (back_pipeline,
|
||||
COGL_PIPELINE_CULL_FACE_MODE_FRONT);
|
||||
|
||||
cogl_framebuffer_draw_primitive (fb, back_pipeline, priv->primitive);
|
||||
|
||||
back_node = clutter_pipeline_node_new (back_pipeline);
|
||||
clutter_paint_node_set_static_name (back_node,
|
||||
"ClutterDeformEffect (back)");
|
||||
clutter_paint_node_add_child (node, back_node);
|
||||
clutter_paint_node_add_primitive (back_node, priv->primitive);
|
||||
|
||||
clutter_paint_node_unref (back_node);
|
||||
cogl_object_unref (back_pipeline);
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (priv->lines_primitive != NULL))
|
||||
{
|
||||
const ClutterColor *red;
|
||||
ClutterPaintNode *lines_node;
|
||||
|
||||
red = clutter_color_get_static (CLUTTER_COLOR_RED);
|
||||
|
||||
lines_node = clutter_color_node_new (red);
|
||||
clutter_paint_node_set_static_name (lines_node,
|
||||
"ClutterDeformEffect (lines)");
|
||||
clutter_paint_node_add_child (node, lines_node);
|
||||
clutter_paint_node_add_primitive (lines_node, priv->lines_primitive);
|
||||
clutter_paint_node_unref (lines_node);
|
||||
CoglContext *ctx =
|
||||
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
CoglPipeline *lines_pipeline = cogl_pipeline_new (ctx);
|
||||
cogl_pipeline_set_color4f (lines_pipeline, 1.0, 0, 0, 1.0);
|
||||
cogl_framebuffer_draw_primitive (fb, lines_pipeline,
|
||||
priv->lines_primitive);
|
||||
cogl_object_unref (lines_pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,13 @@
|
||||
|
||||
#define __CLUTTER_DEPRECATED_H_INSIDE__
|
||||
|
||||
#include "deprecated/clutter-actor.h"
|
||||
#include "deprecated/clutter-box.h"
|
||||
#include "deprecated/clutter-container.h"
|
||||
#include "deprecated/clutter-group.h"
|
||||
#include "deprecated/clutter-rectangle.h"
|
||||
#include "deprecated/clutter-stage.h"
|
||||
#include "deprecated/clutter-timeline.h"
|
||||
|
||||
#undef __CLUTTER_DEPRECATED_H_INSIDE__
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
* @see_also: #ClutterEffect, #ClutterOffscreenEffect
|
||||
*
|
||||
* #ClutterDesaturateEffect is a sub-class of #ClutterEffect that
|
||||
* desaturates the color of an actor and its contents. The strength
|
||||
* desaturates the color of an actor and its contents. The strenght
|
||||
* of the desaturation effect is controllable and animatable through
|
||||
* the #ClutterDesaturateEffect:factor property.
|
||||
*
|
||||
@ -41,6 +41,8 @@
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "clutter-desaturate-effect.h"
|
||||
@ -109,25 +111,16 @@ G_DEFINE_TYPE (ClutterDesaturateEffect,
|
||||
clutter_desaturate_effect,
|
||||
CLUTTER_TYPE_OFFSCREEN_EFFECT);
|
||||
|
||||
static CoglPipeline *
|
||||
clutter_desaturate_effect_create_pipeline (ClutterOffscreenEffect *effect,
|
||||
CoglTexture *texture)
|
||||
{
|
||||
ClutterDesaturateEffect *desaturate_effect =
|
||||
CLUTTER_DESATURATE_EFFECT (effect);
|
||||
|
||||
cogl_pipeline_set_layer_texture (desaturate_effect->pipeline, 0, texture);
|
||||
|
||||
return cogl_object_ref (desaturate_effect->pipeline);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_desaturate_effect_pre_paint (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (effect);
|
||||
ClutterEffectClass *parent_class;
|
||||
|
||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
|
||||
return FALSE;
|
||||
|
||||
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
|
||||
{
|
||||
/* if we don't have support for GLSL shaders then we
|
||||
@ -141,7 +134,52 @@ clutter_desaturate_effect_pre_paint (ClutterEffect *effect,
|
||||
}
|
||||
|
||||
parent_class = CLUTTER_EFFECT_CLASS (clutter_desaturate_effect_parent_class);
|
||||
return parent_class->pre_paint (effect, node, paint_context);
|
||||
if (parent_class->pre_paint (effect, paint_context))
|
||||
{
|
||||
ClutterOffscreenEffect *offscreen_effect =
|
||||
CLUTTER_OFFSCREEN_EFFECT (effect);
|
||||
CoglHandle texture;
|
||||
|
||||
texture = clutter_offscreen_effect_get_texture (offscreen_effect);
|
||||
self->tex_width = cogl_texture_get_width (texture);
|
||||
self->tex_height = cogl_texture_get_height (texture);
|
||||
|
||||
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_desaturate_effect_paint_target (ClutterOffscreenEffect *effect,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (effect);
|
||||
CoglFramebuffer *framebuffer =
|
||||
clutter_paint_context_get_framebuffer (paint_context);
|
||||
ClutterActor *actor;
|
||||
CoglHandle texture;
|
||||
guint8 paint_opacity;
|
||||
|
||||
texture = clutter_offscreen_effect_get_texture (effect);
|
||||
cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
|
||||
paint_opacity = clutter_actor_get_paint_opacity (actor);
|
||||
|
||||
cogl_pipeline_set_color4ub (self->pipeline,
|
||||
paint_opacity,
|
||||
paint_opacity,
|
||||
paint_opacity,
|
||||
paint_opacity);
|
||||
|
||||
cogl_framebuffer_draw_rectangle (framebuffer,
|
||||
self->pipeline,
|
||||
0, 0,
|
||||
cogl_texture_get_width (texture),
|
||||
cogl_texture_get_height (texture));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -216,7 +254,7 @@ clutter_desaturate_effect_class_init (ClutterDesaturateEffectClass *klass)
|
||||
ClutterOffscreenEffectClass *offscreen_class;
|
||||
|
||||
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
||||
offscreen_class->create_pipeline = clutter_desaturate_effect_create_pipeline;
|
||||
offscreen_class->paint_target = clutter_desaturate_effect_paint_target;
|
||||
|
||||
effect_class->pre_paint = clutter_desaturate_effect_pre_paint;
|
||||
|
||||
|
@ -5,11 +5,14 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean _clutter_effect_pre_paint (ClutterEffect *effect,
|
||||
ClutterPaintContext *paint_context);
|
||||
void _clutter_effect_post_paint (ClutterEffect *effect,
|
||||
ClutterPaintContext *paint_context);
|
||||
gboolean _clutter_effect_modify_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume);
|
||||
gboolean _clutter_effect_has_custom_paint_volume (ClutterEffect *effect);
|
||||
void _clutter_effect_paint (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context,
|
||||
ClutterEffectPaintFlags flags);
|
||||
void _clutter_effect_pick (ClutterEffect *effect,
|
||||
|
@ -169,8 +169,6 @@
|
||||
#include "clutter-effect-private.h"
|
||||
#include "clutter-enum-types.h"
|
||||
#include "clutter-marshal.h"
|
||||
#include "clutter-paint-node-private.h"
|
||||
#include "clutter-paint-nodes.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-actor-private.h"
|
||||
|
||||
@ -180,7 +178,6 @@ G_DEFINE_ABSTRACT_TYPE (ClutterEffect,
|
||||
|
||||
static gboolean
|
||||
clutter_effect_real_pre_paint (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
return TRUE;
|
||||
@ -188,7 +185,6 @@ clutter_effect_real_pre_paint (ClutterEffect *effect,
|
||||
|
||||
static void
|
||||
clutter_effect_real_post_paint (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
}
|
||||
@ -200,54 +196,26 @@ clutter_effect_real_modify_paint_volume (ClutterEffect *effect,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
add_actor_node (ClutterEffect *effect,
|
||||
ClutterPaintNode *node)
|
||||
{
|
||||
ClutterPaintNode *actor_node;
|
||||
ClutterActor *actor;
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
|
||||
|
||||
actor_node = clutter_actor_node_new (actor, -1);
|
||||
clutter_paint_node_add_child (node, actor_node);
|
||||
clutter_paint_node_unref (actor_node);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_effect_real_paint_node (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context,
|
||||
ClutterEffectPaintFlags flags)
|
||||
{
|
||||
add_actor_node (effect, node);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_effect_real_paint (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context,
|
||||
ClutterEffectPaintFlags flags)
|
||||
{
|
||||
ClutterEffectClass *effect_class = CLUTTER_EFFECT_GET_CLASS (effect);
|
||||
ClutterActorMeta *actor_meta = CLUTTER_ACTOR_META (effect);
|
||||
ClutterActor *actor;
|
||||
gboolean pre_paint_succeeded;
|
||||
|
||||
/* The default implementation provides a compatibility wrapper for
|
||||
effects that haven't migrated to use the 'paint' virtual yet. This
|
||||
just calls the old pre and post virtuals before chaining on */
|
||||
|
||||
pre_paint_succeeded = effect_class->pre_paint (effect, node,paint_context);
|
||||
pre_paint_succeeded = _clutter_effect_pre_paint (effect, paint_context);
|
||||
|
||||
actor = clutter_actor_meta_get_actor (actor_meta);
|
||||
clutter_actor_continue_paint (actor, paint_context);
|
||||
|
||||
if (pre_paint_succeeded)
|
||||
{
|
||||
effect_class->paint_node (effect, node, paint_context, flags);
|
||||
effect_class->post_paint (effect, node, paint_context);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Just paint the actor as fallback */
|
||||
add_actor_node (effect, node);
|
||||
}
|
||||
_clutter_effect_post_paint (effect, paint_context);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -287,7 +255,6 @@ clutter_effect_class_init (ClutterEffectClass *klass)
|
||||
klass->post_paint = clutter_effect_real_post_paint;
|
||||
klass->modify_paint_volume = clutter_effect_real_modify_paint_volume;
|
||||
klass->paint = clutter_effect_real_paint;
|
||||
klass->paint_node = clutter_effect_real_paint_node;
|
||||
klass->pick = clutter_effect_real_pick;
|
||||
}
|
||||
|
||||
@ -296,18 +263,32 @@ clutter_effect_init (ClutterEffect *self)
|
||||
{
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_effect_pre_paint (ClutterEffect *effect,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE);
|
||||
|
||||
return CLUTTER_EFFECT_GET_CLASS (effect)->pre_paint (effect, paint_context);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_effect_post_paint (ClutterEffect *effect,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_EFFECT (effect));
|
||||
|
||||
CLUTTER_EFFECT_GET_CLASS (effect)->post_paint (effect, paint_context);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_effect_paint (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context,
|
||||
ClutterEffectPaintFlags flags)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_EFFECT (effect));
|
||||
|
||||
CLUTTER_EFFECT_GET_CLASS (effect)->paint (effect,
|
||||
node,
|
||||
paint_context,
|
||||
flags);
|
||||
CLUTTER_EFFECT_GET_CLASS (effect)->paint (effect, paint_context, flags);
|
||||
}
|
||||
|
||||
void
|
||||
@ -368,7 +349,7 @@ _clutter_effect_has_custom_paint_volume (ClutterEffect *effect)
|
||||
* the actor itself so the %CLUTTER_EFFECT_PAINT_ACTOR_DIRTY would still
|
||||
* not be set. The effect can detect this case by keeping track of the
|
||||
* last modelview matrix that was used to render the actor and
|
||||
* verifying that it remains the same in the next paint.
|
||||
* veryifying that it remains the same in the next paint.
|
||||
*
|
||||
* Any other effects that are layered on top of the passed in effect
|
||||
* will still be passed the %CLUTTER_EFFECT_PAINT_ACTOR_DIRTY flag. If
|
||||
@ -392,6 +373,7 @@ clutter_effect_queue_repaint (ClutterEffect *effect)
|
||||
/* If the effect has no actor then nothing needs to be done */
|
||||
if (actor != NULL)
|
||||
_clutter_actor_queue_redraw_full (actor,
|
||||
0, /* flags */
|
||||
NULL, /* clip volume */
|
||||
effect /* effect */);
|
||||
}
|
||||
|
@ -77,21 +77,14 @@ struct _ClutterEffectClass
|
||||
|
||||
/*< public >*/
|
||||
gboolean (* pre_paint) (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context);
|
||||
void (* post_paint) (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context);
|
||||
|
||||
gboolean (* modify_paint_volume) (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume);
|
||||
|
||||
void (* paint) (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context,
|
||||
ClutterEffectPaintFlags flags);
|
||||
void (* paint_node) (ClutterEffect *effect,
|
||||
ClutterPaintNode *node,
|
||||
ClutterPaintContext *paint_context,
|
||||
ClutterEffectPaintFlags flags);
|
||||
void (* pick) (ClutterEffect *effect,
|
||||
|
@ -14,9 +14,9 @@
|
||||
GType
|
||||
@enum_name@_get_type (void)
|
||||
{
|
||||
static size_t g_enum_type_id = 0;
|
||||
static volatile gsize g_enum_type_id__volatile = 0;
|
||||
|
||||
if (g_once_init_enter (&g_enum_type_id))
|
||||
if (g_once_init_enter (&g_enum_type_id__volatile))
|
||||
{
|
||||
static const G@Type@Value values[] = {
|
||||
/*** END value-header ***/
|
||||
@ -28,13 +28,14 @@ GType
|
||||
/*** BEGIN value-tail ***/
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
GType id;
|
||||
GType g_enum_type_id;
|
||||
|
||||
id = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
|
||||
g_enum_type_id =
|
||||
g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
|
||||
|
||||
g_once_init_leave (&g_enum_type_id, id);
|
||||
g_once_init_leave (&g_enum_type_id__volatile, g_enum_type_id);
|
||||
}
|
||||
|
||||
return g_enum_type_id;
|
||||
return g_enum_type_id__volatile;
|
||||
}
|
||||
/*** END value-tail ***/
|
||||
|
@ -127,7 +127,7 @@ typedef enum /*< prefix=CLUTTER_REQUEST >*/
|
||||
* @CLUTTER_EASE_IN_OUT_QUAD: quadratic tweening, combininig
|
||||
* %CLUTTER_EASE_IN_QUAD and %CLUTTER_EASE_OUT_QUAD
|
||||
* @CLUTTER_EASE_IN_CUBIC: cubic tweening
|
||||
* @CLUTTER_EASE_OUT_CUBIC: cubic tweening, inverse of
|
||||
* @CLUTTER_EASE_OUT_CUBIC: cubic tweening, invers of
|
||||
* %CLUTTER_EASE_IN_CUBIC
|
||||
* @CLUTTER_EASE_IN_OUT_CUBIC: cubic tweening, combining
|
||||
* %CLUTTER_EASE_IN_CUBIC and %CLUTTER_EASE_OUT_CUBIC
|
||||
@ -387,6 +387,44 @@ typedef enum
|
||||
CLUTTER_MODIFIER_MASK = 0x5c001fff
|
||||
} ClutterModifierType;
|
||||
|
||||
/**
|
||||
* ClutterKeyboardA11yFlags:
|
||||
* @CLUTTER_A11Y_KEYBOARD_ENABLED:
|
||||
* @CLUTTER_A11Y_TIMEOUT_ENABLED:
|
||||
* @CLUTTER_A11Y_MOUSE_KEYS_ENABLED:
|
||||
* @CLUTTER_A11Y_SLOW_KEYS_ENABLED:
|
||||
* @CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS:
|
||||
* @CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT:
|
||||
* @CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT:
|
||||
* @CLUTTER_A11Y_BOUNCE_KEYS_ENABLED:
|
||||
* @CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT:
|
||||
* @CLUTTER_A11Y_TOGGLE_KEYS_ENABLED:
|
||||
* @CLUTTER_A11Y_STICKY_KEYS_ENABLED:
|
||||
* @CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF:
|
||||
* @CLUTTER_A11Y_STICKY_KEYS_BEEP:
|
||||
* @CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP:
|
||||
*
|
||||
* Keyboard accessibility features applied to a ClutterInputDevice keyboard.
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_A11Y_KEYBOARD_ENABLED = 1 << 0,
|
||||
CLUTTER_A11Y_TIMEOUT_ENABLED = 1 << 1,
|
||||
CLUTTER_A11Y_MOUSE_KEYS_ENABLED = 1 << 2,
|
||||
CLUTTER_A11Y_SLOW_KEYS_ENABLED = 1 << 3,
|
||||
CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS = 1 << 4,
|
||||
CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT = 1 << 5,
|
||||
CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT = 1 << 6,
|
||||
CLUTTER_A11Y_BOUNCE_KEYS_ENABLED = 1 << 7,
|
||||
CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT = 1 << 8,
|
||||
CLUTTER_A11Y_TOGGLE_KEYS_ENABLED = 1 << 9,
|
||||
CLUTTER_A11Y_STICKY_KEYS_ENABLED = 1 << 10,
|
||||
CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF = 1 << 11,
|
||||
CLUTTER_A11Y_STICKY_KEYS_BEEP = 1 << 12,
|
||||
CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13,
|
||||
} ClutterKeyboardA11yFlags;
|
||||
|
||||
/**
|
||||
* ClutterPointerA11yFlags:
|
||||
* @CLUTTER_A11Y_POINTER_ENABLED:
|
||||
@ -475,7 +513,7 @@ typedef enum {
|
||||
* a toplevel, and all parents visible)
|
||||
* @CLUTTER_ACTOR_REALIZED: the resources associated to the actor have been
|
||||
* allocated
|
||||
* @CLUTTER_ACTOR_REACTIVE: the actor 'reacts' to mouse events emitting event
|
||||
* @CLUTTER_ACTOR_REACTIVE: the actor 'reacts' to mouse events emmitting event
|
||||
* signals
|
||||
* @CLUTTER_ACTOR_VISIBLE: the actor has been shown by the application program
|
||||
* @CLUTTER_ACTOR_NO_LAYOUT: the actor provides an explicit layout management
|
||||
@ -802,8 +840,7 @@ typedef enum /*< flags prefix=CLUTTER_EVENT >*/
|
||||
CLUTTER_EVENT_NONE = 0,
|
||||
CLUTTER_EVENT_FLAG_SYNTHETIC = 1 << 0,
|
||||
CLUTTER_EVENT_FLAG_INPUT_METHOD = 1 << 1,
|
||||
CLUTTER_EVENT_FLAG_REPEATED = 1 << 2,
|
||||
CLUTTER_EVENT_FLAG_RELATIVE_MOTION = 1 << 3,
|
||||
CLUTTER_EVENT_FLAG_REPEATED = 1 << 2
|
||||
} ClutterEventFlags;
|
||||
|
||||
/**
|
||||
@ -817,6 +854,10 @@ typedef enum /*< flags prefix=CLUTTER_EVENT >*/
|
||||
* @CLUTTER_BUTTON_PRESS: Pointer button press event
|
||||
* @CLUTTER_BUTTON_RELEASE: Pointer button release event
|
||||
* @CLUTTER_SCROLL: Pointer scroll event
|
||||
* @CLUTTER_STAGE_STATE: Stage state change event
|
||||
* @CLUTTER_DESTROY_NOTIFY: Destroy notification event
|
||||
* @CLUTTER_CLIENT_MESSAGE: Client message event
|
||||
* @CLUTTER_DELETE: Stage delete event
|
||||
* @CLUTTER_TOUCH_BEGIN: A new touch event sequence has started;
|
||||
* event added in 1.10
|
||||
* @CLUTTER_TOUCH_UPDATE: A touch event sequence has been updated;
|
||||
@ -829,11 +870,6 @@ typedef enum /*< flags prefix=CLUTTER_EVENT >*/
|
||||
* determined by its phase field; event added in 1.24
|
||||
* @CLUTTER_TOUCHPAD_SWIPE: A swipe gesture event, the current state is
|
||||
* determined by its phase field; event added in 1.24
|
||||
* @CLUTTER_TOUCHPAD_HOLD: A hold gesture event, the current state is
|
||||
* determined by its phase field. A hold gesture starts when the user places a
|
||||
* finger on the touchpad and ends when all fingers are lifted. It is
|
||||
* cancelled when the finger(s) move past a certain threshold.
|
||||
* Event added in 40.4
|
||||
* @CLUTTER_PROXIMITY_IN: A tool entered in proximity to a tablet;
|
||||
* event added in 1.28
|
||||
* @CLUTTER_PROXIMITY_OUT: A tool left from the proximity area of a tablet;
|
||||
@ -856,24 +892,22 @@ typedef enum /*< prefix=CLUTTER >*/
|
||||
CLUTTER_BUTTON_PRESS,
|
||||
CLUTTER_BUTTON_RELEASE,
|
||||
CLUTTER_SCROLL,
|
||||
CLUTTER_STAGE_STATE,
|
||||
CLUTTER_DESTROY_NOTIFY,
|
||||
CLUTTER_CLIENT_MESSAGE,
|
||||
CLUTTER_DELETE,
|
||||
CLUTTER_TOUCH_BEGIN,
|
||||
CLUTTER_TOUCH_UPDATE,
|
||||
CLUTTER_TOUCH_END,
|
||||
CLUTTER_TOUCH_CANCEL,
|
||||
CLUTTER_TOUCHPAD_PINCH,
|
||||
CLUTTER_TOUCHPAD_SWIPE,
|
||||
CLUTTER_TOUCHPAD_HOLD,
|
||||
CLUTTER_PROXIMITY_IN,
|
||||
CLUTTER_PROXIMITY_OUT,
|
||||
CLUTTER_PAD_BUTTON_PRESS,
|
||||
CLUTTER_PAD_BUTTON_RELEASE,
|
||||
CLUTTER_PAD_STRIP,
|
||||
CLUTTER_PAD_RING,
|
||||
CLUTTER_DEVICE_ADDED,
|
||||
CLUTTER_DEVICE_REMOVED,
|
||||
CLUTTER_IM_COMMIT,
|
||||
CLUTTER_IM_DELETE,
|
||||
CLUTTER_IM_PREEDIT,
|
||||
|
||||
CLUTTER_EVENT_LAST /* helper */
|
||||
} ClutterEventType;
|
||||
@ -902,9 +936,28 @@ typedef enum /*< prefix=CLUTTER_SCROLL >*/
|
||||
CLUTTER_SCROLL_SMOOTH
|
||||
} ClutterScrollDirection;
|
||||
|
||||
/**
|
||||
* ClutterStageState:
|
||||
* @CLUTTER_STAGE_STATE_ACTIVATED: Activated mask
|
||||
*
|
||||
* Stage state masks, used by the #ClutterEvent of type %CLUTTER_STAGE_STATE.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_STAGE_STATE_ACTIVATED = (1 << 3)
|
||||
} ClutterStageState;
|
||||
|
||||
/**
|
||||
* ClutterFeatureFlags:
|
||||
* @CLUTTER_FEATURE_SWAP_THROTTLE: Set if backend throttles buffer swaps.
|
||||
* @CLUTTER_FEATURE_STAGE_STATIC: Set if stage size if fixed (i.e framebuffer)
|
||||
* @CLUTTER_FEATURE_STAGE_CURSOR: Set if stage has a graphical cursor.
|
||||
* @CLUTTER_FEATURE_SHADERS_GLSL: Set if the backend supports GLSL shaders.
|
||||
* @CLUTTER_FEATURE_OFFSCREEN: Set if the backend supports offscreen rendering.
|
||||
* @CLUTTER_FEATURE_STAGE_MULTIPLE: Set if multiple stages are supported.
|
||||
* @CLUTTER_FEATURE_SWAP_EVENTS: Set if the GLX_INTEL_swap_event is supported.
|
||||
*
|
||||
* Runtime flags indicating specific features available via Clutter window
|
||||
* system and graphics backend.
|
||||
@ -913,7 +966,13 @@ typedef enum /*< prefix=CLUTTER_SCROLL >*/
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_FEATURE_SWAP_THROTTLE = (1 << 3),
|
||||
CLUTTER_FEATURE_STAGE_STATIC = (1 << 6),
|
||||
CLUTTER_FEATURE_STAGE_CURSOR = (1 << 8),
|
||||
CLUTTER_FEATURE_SHADERS_GLSL = (1 << 9),
|
||||
CLUTTER_FEATURE_OFFSCREEN = (1 << 10),
|
||||
CLUTTER_FEATURE_STAGE_MULTIPLE = (1 << 11),
|
||||
CLUTTER_FEATURE_SWAP_EVENTS = (1 << 12)
|
||||
} ClutterFeatureFlags;
|
||||
|
||||
/**
|
||||
@ -975,11 +1034,11 @@ typedef enum
|
||||
|
||||
/**
|
||||
* ClutterInputMode:
|
||||
* @CLUTTER_INPUT_MODE_LOGICAL: A logical, virtual device
|
||||
* @CLUTTER_INPUT_MODE_PHYSICAL: A physical device, attached to
|
||||
* a logical device
|
||||
* @CLUTTER_INPUT_MODE_FLOATING: A physical device, not attached
|
||||
* to a logical device
|
||||
* @CLUTTER_INPUT_MODE_MASTER: A master, virtual device
|
||||
* @CLUTTER_INPUT_MODE_SLAVE: A slave, physical device, attached to
|
||||
* a master device
|
||||
* @CLUTTER_INPUT_MODE_FLOATING: A slave, physical device, not attached
|
||||
* to a master device
|
||||
*
|
||||
* The mode for input devices available.
|
||||
*
|
||||
@ -987,8 +1046,8 @@ typedef enum
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_INPUT_MODE_LOGICAL,
|
||||
CLUTTER_INPUT_MODE_PHYSICAL,
|
||||
CLUTTER_INPUT_MODE_MASTER,
|
||||
CLUTTER_INPUT_MODE_SLAVE,
|
||||
CLUTTER_INPUT_MODE_FLOATING
|
||||
} ClutterInputMode;
|
||||
|
||||
@ -1028,20 +1087,6 @@ typedef enum
|
||||
CLUTTER_INPUT_AXIS_LAST
|
||||
} ClutterInputAxis;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_INPUT_AXIS_FLAG_NONE = 0,
|
||||
CLUTTER_INPUT_AXIS_FLAG_X = 1 << CLUTTER_INPUT_AXIS_X,
|
||||
CLUTTER_INPUT_AXIS_FLAG_Y = 1 << CLUTTER_INPUT_AXIS_Y,
|
||||
CLUTTER_INPUT_AXIS_FLAG_PRESSURE = 1 << CLUTTER_INPUT_AXIS_PRESSURE,
|
||||
CLUTTER_INPUT_AXIS_FLAG_XTILT = 1 << CLUTTER_INPUT_AXIS_XTILT,
|
||||
CLUTTER_INPUT_AXIS_FLAG_YTILT = 1 << CLUTTER_INPUT_AXIS_YTILT,
|
||||
CLUTTER_INPUT_AXIS_FLAG_WHEEL = 1 << CLUTTER_INPUT_AXIS_WHEEL,
|
||||
CLUTTER_INPUT_AXIS_FLAG_DISTANCE = 1 << CLUTTER_INPUT_AXIS_DISTANCE,
|
||||
CLUTTER_INPUT_AXIS_FLAG_ROTATION = 1 << CLUTTER_INPUT_AXIS_ROTATION,
|
||||
CLUTTER_INPUT_AXIS_FLAG_SLIDER = 1 << CLUTTER_INPUT_AXIS_SLIDER,
|
||||
} ClutterInputAxisFlags;
|
||||
|
||||
/**
|
||||
* ClutterSnapEdge:
|
||||
* @CLUTTER_SNAP_EDGE_TOP: the top edge
|
||||
@ -1155,7 +1200,7 @@ typedef enum /*< prefix=CLUTTER_TEXTURE >*/
|
||||
*
|
||||
* Since: 0.8
|
||||
*
|
||||
* Deprecated: 1.22: The #ClutterTexture class was the only user of
|
||||
* Deprecated: 1.22: The #ClutterTexture class was the only used ot
|
||||
* this API; use #ClutterImage and clutter_actor_set_content_scaling_filters()
|
||||
* instead.
|
||||
*/
|
||||
@ -1272,6 +1317,8 @@ typedef enum
|
||||
* painting the stages
|
||||
* @CLUTTER_REPAINT_FLAGS_POST_PAINT: Run the repaint function after
|
||||
* painting the stages
|
||||
* @CLUTTER_REPAINT_FLAGS_QUEUE_REDRAW_ON_ADD: Ensure that a new frame
|
||||
* is queued after adding the repaint function
|
||||
*
|
||||
* Flags to pass to clutter_threads_add_repaint_func_full().
|
||||
*
|
||||
@ -1281,6 +1328,7 @@ typedef enum
|
||||
{
|
||||
CLUTTER_REPAINT_FLAGS_PRE_PAINT = 1 << 0,
|
||||
CLUTTER_REPAINT_FLAGS_POST_PAINT = 1 << 1,
|
||||
CLUTTER_REPAINT_FLAGS_QUEUE_REDRAW_ON_ADD = 1 << 2
|
||||
} ClutterRepaintFlags;
|
||||
|
||||
/**
|
||||
@ -1435,6 +1483,24 @@ typedef enum
|
||||
CLUTTER_STEP_MODE_END
|
||||
} ClutterStepMode;
|
||||
|
||||
/**
|
||||
* ClutterZoomAxis:
|
||||
* @CLUTTER_ZOOM_X_AXIS: Scale only on the X axis
|
||||
* @CLUTTER_ZOOM_Y_AXIS: Scale only on the Y axis
|
||||
* @CLUTTER_ZOOM_BOTH: Scale on both axis
|
||||
*
|
||||
* The axis of the constraint that should be applied by the
|
||||
* zooming action.
|
||||
*
|
||||
* Since: 1.12
|
||||
*/
|
||||
typedef enum /*< prefix=CLUTTER_ZOOM >*/
|
||||
{
|
||||
CLUTTER_ZOOM_X_AXIS,
|
||||
CLUTTER_ZOOM_Y_AXIS,
|
||||
CLUTTER_ZOOM_BOTH
|
||||
} ClutterZoomAxis;
|
||||
|
||||
/**
|
||||
* ClutterGestureTriggerEdge:
|
||||
* @CLUTTER_GESTURE_TRIGGER_EDGE_NONE: Tell #ClutterGestureAction that
|
||||
@ -1573,10 +1639,9 @@ typedef enum
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_PAD_FEATURE_BUTTON,
|
||||
CLUTTER_PAD_FEATURE_RING,
|
||||
CLUTTER_PAD_FEATURE_STRIP,
|
||||
} ClutterInputDevicePadFeature;
|
||||
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE,
|
||||
CLUTTER_INPUT_DEVICE_MAPPING_RELATIVE,
|
||||
} ClutterInputDeviceMapping;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@ -1616,18 +1681,6 @@ typedef enum
|
||||
CLUTTER_INPUT_PANEL_STATE_TOGGLE,
|
||||
} ClutterInputPanelState;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_PREEDIT_RESET_CLEAR,
|
||||
CLUTTER_PREEDIT_RESET_COMMIT,
|
||||
} ClutterPreeditResetMode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_PHASE_CAPTURE,
|
||||
CLUTTER_PHASE_BUBBLE,
|
||||
} ClutterEventPhase;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ENUMS_H__ */
|
||||
|
@ -18,6 +18,7 @@ gboolean _clutter_event_process_filters (ClutterEvent *eve
|
||||
|
||||
/* clears the event queue inside the main context */
|
||||
void _clutter_clear_events_queue (void);
|
||||
void _clutter_clear_events_queue_for_stage (ClutterStage *stage);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_event_set_platform_data (ClutterEvent *event,
|
||||
|
@ -73,6 +73,8 @@ typedef struct _ClutterEventFilter {
|
||||
gpointer user_data;
|
||||
} ClutterEventFilter;
|
||||
|
||||
static GHashTable *all_events = NULL;
|
||||
|
||||
G_DEFINE_BOXED_TYPE (ClutterEvent, clutter_event,
|
||||
clutter_event_copy,
|
||||
clutter_event_free);
|
||||
@ -94,6 +96,15 @@ G_DEFINE_BOXED_TYPE (ClutterEventSequence, clutter_event_sequence,
|
||||
clutter_event_sequence_copy,
|
||||
clutter_event_sequence_free);
|
||||
|
||||
static gboolean
|
||||
is_event_allocated (const ClutterEvent *event)
|
||||
{
|
||||
if (all_events == NULL)
|
||||
return FALSE;
|
||||
|
||||
return g_hash_table_lookup (all_events, event) != NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* _clutter_event_get_platform_data:
|
||||
* @event: a #ClutterEvent
|
||||
@ -107,6 +118,9 @@ G_DEFINE_BOXED_TYPE (ClutterEventSequence, clutter_event_sequence,
|
||||
gpointer
|
||||
_clutter_event_get_platform_data (const ClutterEvent *event)
|
||||
{
|
||||
if (!is_event_allocated (event))
|
||||
return NULL;
|
||||
|
||||
return ((ClutterEventPrivate *) event)->platform_data;
|
||||
}
|
||||
|
||||
@ -123,6 +137,9 @@ void
|
||||
_clutter_event_set_platform_data (ClutterEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
if (!is_event_allocated (event))
|
||||
return;
|
||||
|
||||
((ClutterEventPrivate *) event)->platform_data = data;
|
||||
}
|
||||
|
||||
@ -130,6 +147,9 @@ void
|
||||
_clutter_event_set_pointer_emulated (ClutterEvent *event,
|
||||
gboolean is_emulated)
|
||||
{
|
||||
if (!is_event_allocated (event))
|
||||
return;
|
||||
|
||||
((ClutterEventPrivate *) event)->is_pointer_emulated = !!is_emulated;
|
||||
}
|
||||
|
||||
@ -384,6 +404,10 @@ clutter_event_get_position (const ClutterEvent *event,
|
||||
case CLUTTER_NOTHING:
|
||||
case CLUTTER_KEY_PRESS:
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
case CLUTTER_STAGE_STATE:
|
||||
case CLUTTER_DESTROY_NOTIFY:
|
||||
case CLUTTER_CLIENT_MESSAGE:
|
||||
case CLUTTER_DELETE:
|
||||
case CLUTTER_EVENT_LAST:
|
||||
case CLUTTER_PROXIMITY_IN:
|
||||
case CLUTTER_PROXIMITY_OUT:
|
||||
@ -391,11 +415,6 @@ clutter_event_get_position (const ClutterEvent *event,
|
||||
case CLUTTER_PAD_BUTTON_RELEASE:
|
||||
case CLUTTER_PAD_STRIP:
|
||||
case CLUTTER_PAD_RING:
|
||||
case CLUTTER_DEVICE_ADDED:
|
||||
case CLUTTER_DEVICE_REMOVED:
|
||||
case CLUTTER_IM_COMMIT:
|
||||
case CLUTTER_IM_DELETE:
|
||||
case CLUTTER_IM_PREEDIT:
|
||||
graphene_point_init (position, 0.f, 0.f);
|
||||
break;
|
||||
|
||||
@ -433,11 +452,6 @@ clutter_event_get_position (const ClutterEvent *event,
|
||||
graphene_point_init (position, event->touchpad_swipe.x,
|
||||
event->touchpad_swipe.y);
|
||||
break;
|
||||
|
||||
case CLUTTER_TOUCHPAD_HOLD:
|
||||
graphene_point_init (position, event->touchpad_hold.x,
|
||||
event->touchpad_hold.y);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
@ -464,6 +478,10 @@ clutter_event_set_coords (ClutterEvent *event,
|
||||
case CLUTTER_NOTHING:
|
||||
case CLUTTER_KEY_PRESS:
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
case CLUTTER_STAGE_STATE:
|
||||
case CLUTTER_DESTROY_NOTIFY:
|
||||
case CLUTTER_CLIENT_MESSAGE:
|
||||
case CLUTTER_DELETE:
|
||||
case CLUTTER_EVENT_LAST:
|
||||
case CLUTTER_PROXIMITY_IN:
|
||||
case CLUTTER_PROXIMITY_OUT:
|
||||
@ -471,11 +489,6 @@ clutter_event_set_coords (ClutterEvent *event,
|
||||
case CLUTTER_PAD_BUTTON_RELEASE:
|
||||
case CLUTTER_PAD_STRIP:
|
||||
case CLUTTER_PAD_RING:
|
||||
case CLUTTER_DEVICE_ADDED:
|
||||
case CLUTTER_DEVICE_REMOVED:
|
||||
case CLUTTER_IM_COMMIT:
|
||||
case CLUTTER_IM_DELETE:
|
||||
case CLUTTER_IM_PREEDIT:
|
||||
break;
|
||||
|
||||
case CLUTTER_ENTER:
|
||||
@ -517,11 +530,6 @@ clutter_event_set_coords (ClutterEvent *event,
|
||||
event->touchpad_swipe.x = x;
|
||||
event->touchpad_swipe.y = y;
|
||||
break;
|
||||
|
||||
case CLUTTER_TOUCHPAD_HOLD:
|
||||
event->touchpad_hold.x = x;
|
||||
event->touchpad_hold.y = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -707,6 +715,9 @@ clutter_event_set_scroll_delta (ClutterEvent *event,
|
||||
g_return_if_fail (event != NULL);
|
||||
g_return_if_fail (event->type == CLUTTER_SCROLL);
|
||||
|
||||
if (!is_event_allocated (event))
|
||||
return;
|
||||
|
||||
event->scroll.direction = CLUTTER_SCROLL_SMOOTH;
|
||||
|
||||
((ClutterEventPrivate *) event)->delta_x = dx;
|
||||
@ -737,8 +748,13 @@ clutter_event_get_scroll_delta (const ClutterEvent *event,
|
||||
g_return_if_fail (event->type == CLUTTER_SCROLL);
|
||||
g_return_if_fail (event->scroll.direction == CLUTTER_SCROLL_SMOOTH);
|
||||
|
||||
delta_x = ((ClutterEventPrivate *) event)->delta_x;
|
||||
delta_y = ((ClutterEventPrivate *) event)->delta_y;
|
||||
delta_x = delta_y = 0;
|
||||
|
||||
if (is_event_allocated (event))
|
||||
{
|
||||
delta_x = ((ClutterEventPrivate *) event)->delta_x;
|
||||
delta_y = ((ClutterEventPrivate *) event)->delta_y;
|
||||
}
|
||||
|
||||
if (dx != NULL)
|
||||
*dx = delta_x;
|
||||
@ -833,6 +849,27 @@ clutter_event_set_button (ClutterEvent *event,
|
||||
event->button.button = button;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_event_get_click_count:
|
||||
* @event: a #ClutterEvent of type %CLUTTER_BUTTON_PRESS or
|
||||
* of type %CLUTTER_BUTTON_RELEASE
|
||||
*
|
||||
* Retrieves the number of clicks of @event
|
||||
*
|
||||
* Return value: the click count
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
guint32
|
||||
clutter_event_get_click_count (const ClutterEvent *event)
|
||||
{
|
||||
g_return_val_if_fail (event != NULL, 0);
|
||||
g_return_val_if_fail (event->type == CLUTTER_BUTTON_PRESS ||
|
||||
event->type == CLUTTER_BUTTON_RELEASE, 0);
|
||||
|
||||
return event->button.click_count;
|
||||
}
|
||||
|
||||
/* keys */
|
||||
|
||||
/**
|
||||
@ -991,6 +1028,29 @@ clutter_event_get_event_sequence (const ClutterEvent *event)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_event_get_device_id:
|
||||
* @event: a clutter event
|
||||
*
|
||||
* Retrieves the events device id if set.
|
||||
*
|
||||
* Return value: A unique identifier for the device or -1 if the event has
|
||||
* no specific device set.
|
||||
*/
|
||||
gint
|
||||
clutter_event_get_device_id (const ClutterEvent *event)
|
||||
{
|
||||
ClutterInputDevice *device = NULL;
|
||||
|
||||
g_return_val_if_fail (event != NULL, CLUTTER_POINTER_DEVICE);
|
||||
|
||||
device = clutter_event_get_device (event);
|
||||
if (device != NULL)
|
||||
return clutter_input_device_get_device_id (device);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_event_get_device_type:
|
||||
* @event: a #ClutterEvent
|
||||
@ -1029,20 +1089,24 @@ void
|
||||
clutter_event_set_device (ClutterEvent *event,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
|
||||
|
||||
g_return_if_fail (event != NULL);
|
||||
g_return_if_fail (device == NULL || CLUTTER_IS_INPUT_DEVICE (device));
|
||||
|
||||
g_set_object (&real_event->device, device);
|
||||
if (is_event_allocated (event))
|
||||
{
|
||||
ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
|
||||
|
||||
g_set_object (&real_event->device, device);
|
||||
}
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_NOTHING:
|
||||
case CLUTTER_STAGE_STATE:
|
||||
case CLUTTER_DESTROY_NOTIFY:
|
||||
case CLUTTER_CLIENT_MESSAGE:
|
||||
case CLUTTER_DELETE:
|
||||
case CLUTTER_EVENT_LAST:
|
||||
case CLUTTER_IM_COMMIT:
|
||||
case CLUTTER_IM_DELETE:
|
||||
case CLUTTER_IM_PREEDIT:
|
||||
break;
|
||||
|
||||
case CLUTTER_ENTER:
|
||||
@ -1077,7 +1141,6 @@ clutter_event_set_device (ClutterEvent *event,
|
||||
|
||||
case CLUTTER_TOUCHPAD_PINCH:
|
||||
case CLUTTER_TOUCHPAD_SWIPE:
|
||||
case CLUTTER_TOUCHPAD_HOLD:
|
||||
/* Rely on priv data for these */
|
||||
break;
|
||||
|
||||
@ -1098,11 +1161,6 @@ clutter_event_set_device (ClutterEvent *event,
|
||||
case CLUTTER_PAD_RING:
|
||||
event->pad_ring.device = device;
|
||||
break;
|
||||
|
||||
case CLUTTER_DEVICE_ADDED:
|
||||
case CLUTTER_DEVICE_REMOVED:
|
||||
event->device.device = device;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1127,19 +1185,24 @@ ClutterInputDevice *
|
||||
clutter_event_get_device (const ClutterEvent *event)
|
||||
{
|
||||
ClutterInputDevice *device = NULL;
|
||||
ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
|
||||
|
||||
g_return_val_if_fail (event != NULL, NULL);
|
||||
|
||||
if (real_event->device != NULL)
|
||||
return real_event->device;
|
||||
if (is_event_allocated (event))
|
||||
{
|
||||
ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
|
||||
|
||||
if (real_event->device != NULL)
|
||||
return real_event->device;
|
||||
}
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_NOTHING:
|
||||
case CLUTTER_IM_COMMIT:
|
||||
case CLUTTER_IM_DELETE:
|
||||
case CLUTTER_IM_PREEDIT:
|
||||
case CLUTTER_STAGE_STATE:
|
||||
case CLUTTER_DESTROY_NOTIFY:
|
||||
case CLUTTER_CLIENT_MESSAGE:
|
||||
case CLUTTER_DELETE:
|
||||
case CLUTTER_EVENT_LAST:
|
||||
break;
|
||||
|
||||
@ -1175,7 +1238,6 @@ clutter_event_get_device (const ClutterEvent *event)
|
||||
|
||||
case CLUTTER_TOUCHPAD_PINCH:
|
||||
case CLUTTER_TOUCHPAD_SWIPE:
|
||||
case CLUTTER_TOUCHPAD_HOLD:
|
||||
/* Rely on priv data for these */
|
||||
break;
|
||||
|
||||
@ -1196,11 +1258,6 @@ clutter_event_get_device (const ClutterEvent *event)
|
||||
case CLUTTER_PAD_RING:
|
||||
device = event->pad_ring.device;
|
||||
break;
|
||||
|
||||
case CLUTTER_DEVICE_ADDED:
|
||||
case CLUTTER_DEVICE_REMOVED:
|
||||
device = event->device.device;
|
||||
break;
|
||||
}
|
||||
|
||||
return device;
|
||||
@ -1219,11 +1276,14 @@ void
|
||||
clutter_event_set_device_tool (ClutterEvent *event,
|
||||
ClutterInputDeviceTool *tool)
|
||||
{
|
||||
ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
|
||||
|
||||
g_return_if_fail (event != NULL);
|
||||
|
||||
real_event->tool = tool;
|
||||
if (is_event_allocated (event))
|
||||
{
|
||||
ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
|
||||
|
||||
real_event->tool = tool;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1239,11 +1299,16 @@ clutter_event_set_device_tool (ClutterEvent *event,
|
||||
ClutterInputDeviceTool *
|
||||
clutter_event_get_device_tool (const ClutterEvent *event)
|
||||
{
|
||||
ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
|
||||
|
||||
g_return_val_if_fail (event != NULL, NULL);
|
||||
|
||||
return real_event->tool;
|
||||
if (is_event_allocated (event))
|
||||
{
|
||||
ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
|
||||
|
||||
return real_event->tool;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1260,11 +1325,16 @@ clutter_event_new (ClutterEventType type)
|
||||
ClutterEvent *new_event;
|
||||
ClutterEventPrivate *priv;
|
||||
|
||||
priv = g_new0 (ClutterEventPrivate, 1);
|
||||
priv = g_slice_new0 (ClutterEventPrivate);
|
||||
|
||||
new_event = (ClutterEvent *) priv;
|
||||
new_event->type = new_event->any.type = type;
|
||||
|
||||
if (G_UNLIKELY (all_events == NULL))
|
||||
all_events = g_hash_table_new (NULL, NULL);
|
||||
|
||||
g_hash_table_replace (all_events, priv, GUINT_TO_POINTER (1));
|
||||
|
||||
return new_event;
|
||||
}
|
||||
|
||||
@ -1281,7 +1351,8 @@ clutter_event_copy (const ClutterEvent *event)
|
||||
{
|
||||
ClutterEvent *new_event;
|
||||
ClutterEventPrivate *new_real_event;
|
||||
ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
|
||||
ClutterInputDevice *device;
|
||||
gint n_axes = 0;
|
||||
|
||||
g_return_val_if_fail (event != NULL, NULL);
|
||||
|
||||
@ -1290,45 +1361,45 @@ clutter_event_copy (const ClutterEvent *event)
|
||||
|
||||
*new_event = *event;
|
||||
|
||||
g_set_object (&new_real_event->device, real_event->device);
|
||||
g_set_object (&new_real_event->source_device, real_event->source_device);
|
||||
new_real_event->delta_x = real_event->delta_x;
|
||||
new_real_event->delta_y = real_event->delta_y;
|
||||
new_real_event->is_pointer_emulated = real_event->is_pointer_emulated;
|
||||
new_real_event->base_state = real_event->base_state;
|
||||
new_real_event->button_state = real_event->button_state;
|
||||
new_real_event->latched_state = real_event->latched_state;
|
||||
new_real_event->locked_state = real_event->locked_state;
|
||||
new_real_event->tool = real_event->tool;
|
||||
if (is_event_allocated (event))
|
||||
{
|
||||
ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
|
||||
|
||||
g_set_object (&new_real_event->device, real_event->device);
|
||||
g_set_object (&new_real_event->source_device, real_event->source_device);
|
||||
new_real_event->delta_x = real_event->delta_x;
|
||||
new_real_event->delta_y = real_event->delta_y;
|
||||
new_real_event->is_pointer_emulated = real_event->is_pointer_emulated;
|
||||
new_real_event->base_state = real_event->base_state;
|
||||
new_real_event->button_state = real_event->button_state;
|
||||
new_real_event->latched_state = real_event->latched_state;
|
||||
new_real_event->locked_state = real_event->locked_state;
|
||||
new_real_event->tool = real_event->tool;
|
||||
}
|
||||
|
||||
device = clutter_event_get_device (event);
|
||||
if (device != NULL)
|
||||
n_axes = clutter_input_device_get_n_axes (device);
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
if (event->button.axes != NULL)
|
||||
{
|
||||
new_event->button.axes =
|
||||
g_memdup2 (event->button.axes,
|
||||
sizeof (double) * CLUTTER_INPUT_AXIS_LAST);
|
||||
}
|
||||
new_event->button.axes = g_memdup (event->button.axes,
|
||||
sizeof (gdouble) * n_axes);
|
||||
break;
|
||||
|
||||
case CLUTTER_SCROLL:
|
||||
if (event->scroll.axes != NULL)
|
||||
{
|
||||
new_event->scroll.axes =
|
||||
g_memdup2 (event->scroll.axes,
|
||||
sizeof (double) * CLUTTER_INPUT_AXIS_LAST);
|
||||
}
|
||||
new_event->scroll.axes = g_memdup (event->scroll.axes,
|
||||
sizeof (gdouble) * n_axes);
|
||||
break;
|
||||
|
||||
case CLUTTER_MOTION:
|
||||
if (event->motion.axes != NULL)
|
||||
{
|
||||
new_event->motion.axes =
|
||||
g_memdup2 (event->motion.axes,
|
||||
sizeof (double) * CLUTTER_INPUT_AXIS_LAST);
|
||||
}
|
||||
new_event->motion.axes = g_memdup (event->motion.axes,
|
||||
sizeof (gdouble) * n_axes);
|
||||
break;
|
||||
|
||||
case CLUTTER_TOUCH_BEGIN:
|
||||
@ -1336,26 +1407,19 @@ clutter_event_copy (const ClutterEvent *event)
|
||||
case CLUTTER_TOUCH_END:
|
||||
case CLUTTER_TOUCH_CANCEL:
|
||||
if (event->touch.axes != NULL)
|
||||
{
|
||||
new_event->touch.axes =
|
||||
g_memdup2 (event->touch.axes,
|
||||
sizeof (double) * CLUTTER_INPUT_AXIS_LAST);
|
||||
}
|
||||
break;
|
||||
|
||||
case CLUTTER_DEVICE_ADDED:
|
||||
case CLUTTER_DEVICE_REMOVED:
|
||||
new_event->device.device = event->device.device;
|
||||
break;
|
||||
case CLUTTER_IM_COMMIT:
|
||||
case CLUTTER_IM_PREEDIT:
|
||||
new_event->im.text = g_strdup (event->im.text);
|
||||
new_event->touch.axes = g_memdup (event->touch.axes,
|
||||
sizeof (gdouble) * n_axes);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_event_allocated (event))
|
||||
_clutter_backend_copy_event_data (clutter_get_default_backend (),
|
||||
event,
|
||||
new_event);
|
||||
|
||||
return new_event;
|
||||
}
|
||||
|
||||
@ -1370,10 +1434,15 @@ clutter_event_free (ClutterEvent *event)
|
||||
{
|
||||
if (G_LIKELY (event != NULL))
|
||||
{
|
||||
ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
|
||||
_clutter_backend_free_event_data (clutter_get_default_backend (), event);
|
||||
|
||||
g_clear_object (&real_event->device);
|
||||
g_clear_object (&real_event->source_device);
|
||||
if (is_event_allocated (event))
|
||||
{
|
||||
ClutterEventPrivate *real_event = (ClutterEventPrivate *) event;
|
||||
|
||||
g_clear_object (&real_event->device);
|
||||
g_clear_object (&real_event->source_device);
|
||||
}
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
@ -1397,16 +1466,12 @@ clutter_event_free (ClutterEvent *event)
|
||||
g_free (event->touch.axes);
|
||||
break;
|
||||
|
||||
case CLUTTER_IM_COMMIT:
|
||||
case CLUTTER_IM_PREEDIT:
|
||||
g_free (event->im.text);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_free ((ClutterEventPrivate *) event);
|
||||
g_hash_table_remove (all_events, event);
|
||||
g_slice_free (ClutterEventPrivate, (ClutterEventPrivate *) event);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1424,11 +1489,40 @@ ClutterEvent *
|
||||
clutter_event_get (void)
|
||||
{
|
||||
ClutterMainContext *context = _clutter_context_get_default ();
|
||||
ClutterEvent *event;
|
||||
|
||||
event = g_async_queue_try_pop (context->events_queue);
|
||||
if (context->events_queue == NULL)
|
||||
return NULL;
|
||||
|
||||
return event;
|
||||
if (g_queue_is_empty (context->events_queue))
|
||||
return NULL;
|
||||
|
||||
return g_queue_pop_tail (context->events_queue);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_event_peek:
|
||||
*
|
||||
* Returns a pointer to the first event from the event queue but
|
||||
* does not remove it.
|
||||
*
|
||||
* Return value: (transfer none): A #ClutterEvent or NULL if queue empty.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
ClutterEvent *
|
||||
clutter_event_peek (void)
|
||||
{
|
||||
ClutterMainContext *context = _clutter_context_get_default ();
|
||||
|
||||
g_return_val_if_fail (context != NULL, NULL);
|
||||
|
||||
if (context->events_queue == NULL)
|
||||
return NULL;
|
||||
|
||||
if (g_queue_is_empty (context->events_queue))
|
||||
return NULL;
|
||||
|
||||
return g_queue_peek_tail (context->events_queue);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1436,9 +1530,21 @@ _clutter_event_push (const ClutterEvent *event,
|
||||
gboolean do_copy)
|
||||
{
|
||||
ClutterMainContext *context = _clutter_context_get_default ();
|
||||
ClutterInputDevice *device;
|
||||
|
||||
g_assert (context != NULL);
|
||||
|
||||
if (context->events_queue == NULL)
|
||||
context->events_queue = g_queue_new ();
|
||||
|
||||
/* disabled devices don't propagate events */
|
||||
device = clutter_event_get_device (event);
|
||||
if (device != NULL)
|
||||
{
|
||||
if (!clutter_input_device_get_enabled (device))
|
||||
return;
|
||||
}
|
||||
|
||||
if (do_copy)
|
||||
{
|
||||
ClutterEvent *copy;
|
||||
@ -1447,8 +1553,7 @@ _clutter_event_push (const ClutterEvent *event,
|
||||
event = copy;
|
||||
}
|
||||
|
||||
g_async_queue_push (context->events_queue, (gpointer) event);
|
||||
g_main_context_wakeup (NULL);
|
||||
g_queue_push_head (context->events_queue, (gpointer) event);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1485,7 +1590,10 @@ clutter_events_pending (void)
|
||||
|
||||
g_return_val_if_fail (context != NULL, FALSE);
|
||||
|
||||
return g_async_queue_length (context->events_queue) > 0;
|
||||
if (context->events_queue == NULL)
|
||||
return FALSE;
|
||||
|
||||
return g_queue_is_empty (context->events_queue) == FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1555,6 +1663,9 @@ clutter_event_get_source_device (const ClutterEvent *event)
|
||||
{
|
||||
ClutterEventPrivate *real_event;
|
||||
|
||||
if (!is_event_allocated (event))
|
||||
return NULL;
|
||||
|
||||
real_event = (ClutterEventPrivate *) event;
|
||||
|
||||
if (real_event->source_device != NULL)
|
||||
@ -1583,6 +1694,9 @@ clutter_event_set_source_device (ClutterEvent *event,
|
||||
g_return_if_fail (event != NULL);
|
||||
g_return_if_fail (device == NULL || CLUTTER_IS_INPUT_DEVICE (device));
|
||||
|
||||
if (!is_event_allocated (event))
|
||||
return;
|
||||
|
||||
real_event = (ClutterEventPrivate *) event;
|
||||
g_set_object (&real_event->source_device, device);
|
||||
}
|
||||
@ -1603,10 +1717,15 @@ clutter_event_get_axes (const ClutterEvent *event,
|
||||
guint *n_axes)
|
||||
{
|
||||
gdouble *retval = NULL;
|
||||
guint len = 0;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_NOTHING:
|
||||
case CLUTTER_STAGE_STATE:
|
||||
case CLUTTER_DESTROY_NOTIFY:
|
||||
case CLUTTER_CLIENT_MESSAGE:
|
||||
case CLUTTER_DELETE:
|
||||
case CLUTTER_ENTER:
|
||||
case CLUTTER_LEAVE:
|
||||
case CLUTTER_KEY_PRESS:
|
||||
@ -1614,8 +1733,6 @@ clutter_event_get_axes (const ClutterEvent *event,
|
||||
case CLUTTER_EVENT_LAST:
|
||||
case CLUTTER_PROXIMITY_IN:
|
||||
case CLUTTER_PROXIMITY_OUT:
|
||||
case CLUTTER_DEVICE_ADDED:
|
||||
case CLUTTER_DEVICE_REMOVED:
|
||||
break;
|
||||
|
||||
case CLUTTER_SCROLL:
|
||||
@ -1640,19 +1757,26 @@ clutter_event_get_axes (const ClutterEvent *event,
|
||||
|
||||
case CLUTTER_TOUCHPAD_PINCH:
|
||||
case CLUTTER_TOUCHPAD_SWIPE:
|
||||
case CLUTTER_TOUCHPAD_HOLD:
|
||||
case CLUTTER_PAD_BUTTON_PRESS:
|
||||
case CLUTTER_PAD_BUTTON_RELEASE:
|
||||
case CLUTTER_PAD_STRIP:
|
||||
case CLUTTER_PAD_RING:
|
||||
case CLUTTER_IM_COMMIT:
|
||||
case CLUTTER_IM_DELETE:
|
||||
case CLUTTER_IM_PREEDIT:
|
||||
break;
|
||||
}
|
||||
|
||||
if (retval != NULL)
|
||||
{
|
||||
ClutterInputDevice *device;
|
||||
|
||||
device = clutter_event_get_device (event);
|
||||
if (device != NULL)
|
||||
len = clutter_input_device_get_n_axes (device);
|
||||
else
|
||||
retval = NULL;
|
||||
}
|
||||
|
||||
if (n_axes)
|
||||
*n_axes = CLUTTER_INPUT_AXIS_LAST;
|
||||
*n_axes = len;
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -1771,6 +1895,9 @@ clutter_event_is_pointer_emulated (const ClutterEvent *event)
|
||||
{
|
||||
g_return_val_if_fail (event != NULL, FALSE);
|
||||
|
||||
if (!is_event_allocated (event))
|
||||
return FALSE;
|
||||
|
||||
return ((ClutterEventPrivate *) event)->is_pointer_emulated;
|
||||
}
|
||||
|
||||
@ -1822,7 +1949,7 @@ clutter_event_add_filter (ClutterStage *stage,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterMainContext *context = _clutter_context_get_default ();
|
||||
ClutterEventFilter *event_filter = g_new0 (ClutterEventFilter, 1);
|
||||
ClutterEventFilter *event_filter = g_slice_new (ClutterEventFilter);
|
||||
static guint event_filter_id = 0;
|
||||
|
||||
event_filter->stage = stage;
|
||||
@ -1863,7 +1990,7 @@ clutter_event_remove_filter (guint id)
|
||||
event_filter->notify (event_filter->user_data);
|
||||
|
||||
context->event_filters = g_list_delete_link (context->event_filters, l);
|
||||
g_free (event_filter);
|
||||
g_slice_free (ClutterEventFilter, event_filter);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1886,15 +2013,12 @@ clutter_event_get_touchpad_gesture_finger_count (const ClutterEvent *event)
|
||||
{
|
||||
g_return_val_if_fail (event != NULL, 0);
|
||||
g_return_val_if_fail (event->type == CLUTTER_TOUCHPAD_SWIPE ||
|
||||
event->type == CLUTTER_TOUCHPAD_PINCH ||
|
||||
event->type == CLUTTER_TOUCHPAD_HOLD, 0);
|
||||
event->type == CLUTTER_TOUCHPAD_PINCH, 0);
|
||||
|
||||
if (event->type == CLUTTER_TOUCHPAD_SWIPE)
|
||||
return event->touchpad_swipe.n_fingers;
|
||||
else if (event->type == CLUTTER_TOUCHPAD_PINCH)
|
||||
return event->touchpad_pinch.n_fingers;
|
||||
else if (event->type == CLUTTER_TOUCHPAD_HOLD)
|
||||
return event->touchpad_hold.n_fingers;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1953,15 +2077,12 @@ clutter_event_get_gesture_phase (const ClutterEvent *event)
|
||||
{
|
||||
g_return_val_if_fail (event != NULL, 0);
|
||||
g_return_val_if_fail (event->type == CLUTTER_TOUCHPAD_PINCH ||
|
||||
event->type == CLUTTER_TOUCHPAD_SWIPE ||
|
||||
event->type == CLUTTER_TOUCHPAD_HOLD, 0);
|
||||
event->type == CLUTTER_TOUCHPAD_SWIPE, 0);
|
||||
|
||||
if (event->type == CLUTTER_TOUCHPAD_PINCH)
|
||||
return event->touchpad_pinch.phase;
|
||||
else if (event->type == CLUTTER_TOUCHPAD_SWIPE)
|
||||
return event->touchpad_swipe.phase;
|
||||
else if (event->type == CLUTTER_TOUCHPAD_HOLD)
|
||||
return event->touchpad_hold.phase;
|
||||
|
||||
/* Shouldn't ever happen */
|
||||
return CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN;
|
||||
@ -1987,8 +2108,7 @@ clutter_event_get_gesture_motion_delta (const ClutterEvent *event,
|
||||
{
|
||||
g_return_if_fail (event != NULL);
|
||||
g_return_if_fail (event->type == CLUTTER_TOUCHPAD_PINCH ||
|
||||
event->type == CLUTTER_TOUCHPAD_SWIPE ||
|
||||
event->type == CLUTTER_TOUCHPAD_HOLD);
|
||||
event->type == CLUTTER_TOUCHPAD_SWIPE);
|
||||
|
||||
if (event->type == CLUTTER_TOUCHPAD_PINCH)
|
||||
{
|
||||
@ -2004,59 +2124,8 @@ clutter_event_get_gesture_motion_delta (const ClutterEvent *event,
|
||||
if (dy)
|
||||
*dy = event->touchpad_swipe.dy;
|
||||
}
|
||||
else if (event->type == CLUTTER_TOUCHPAD_HOLD)
|
||||
{
|
||||
if (dx)
|
||||
*dx = 0;
|
||||
if (dy)
|
||||
*dy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_event_get_gesture_motion_delta_unaccelerated:
|
||||
* @event: A clutter touchpad gesture event
|
||||
* @dx: (out) (allow-none): the displacement relative to the pointer
|
||||
* position in the X axis, or %NULL
|
||||
* @dy: (out) (allow-none): the displacement relative to the pointer
|
||||
* position in the Y axis, or %NULL
|
||||
*
|
||||
* Returns the unaccelerated gesture motion deltas relative to the current
|
||||
* pointer position. Unlike clutter_event_get_gesture_motion_delta(),
|
||||
* pointer acceleration is ignored.
|
||||
**/
|
||||
void
|
||||
clutter_event_get_gesture_motion_delta_unaccelerated (const ClutterEvent *event,
|
||||
gdouble *dx,
|
||||
gdouble *dy)
|
||||
{
|
||||
g_return_if_fail (event != NULL);
|
||||
g_return_if_fail (event->type == CLUTTER_TOUCHPAD_PINCH ||
|
||||
event->type == CLUTTER_TOUCHPAD_SWIPE ||
|
||||
event->type == CLUTTER_TOUCHPAD_HOLD);
|
||||
|
||||
if (event->type == CLUTTER_TOUCHPAD_PINCH)
|
||||
{
|
||||
if (dx)
|
||||
*dx = event->touchpad_pinch.dx_unaccel;
|
||||
if (dy)
|
||||
*dy = event->touchpad_pinch.dy_unaccel;
|
||||
}
|
||||
else if (event->type == CLUTTER_TOUCHPAD_SWIPE)
|
||||
{
|
||||
if (dx)
|
||||
*dx = event->touchpad_swipe.dx_unaccel;
|
||||
if (dy)
|
||||
*dy = event->touchpad_swipe.dy_unaccel;
|
||||
}
|
||||
else if (event->type == CLUTTER_TOUCHPAD_HOLD)
|
||||
{
|
||||
if (dx)
|
||||
*dx = 0;
|
||||
if (dy)
|
||||
*dy = 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* clutter_event_get_scroll_source:
|
||||
* @event: an scroll event
|
||||
@ -2177,58 +2246,3 @@ clutter_event_get_pad_event_details (const ClutterEvent *event,
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
clutter_event_get_event_code (const ClutterEvent *event)
|
||||
{
|
||||
if (event->type == CLUTTER_KEY_PRESS ||
|
||||
event->type == CLUTTER_KEY_RELEASE)
|
||||
return event->key.evdev_code;
|
||||
else if (event->type == CLUTTER_BUTTON_PRESS ||
|
||||
event->type == CLUTTER_BUTTON_RELEASE)
|
||||
return event->button.evdev_code;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t
|
||||
clutter_event_sequence_get_slot (const ClutterEventSequence *sequence)
|
||||
{
|
||||
g_return_val_if_fail (sequence != NULL, -1);
|
||||
|
||||
return GPOINTER_TO_INT (sequence) - 1;
|
||||
}
|
||||
|
||||
int64_t
|
||||
clutter_event_get_time_us (const ClutterEvent *event)
|
||||
{
|
||||
if (event->type == CLUTTER_MOTION)
|
||||
return event->motion.time_us;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_event_get_relative_motion (const ClutterEvent *event,
|
||||
double *dx,
|
||||
double *dy,
|
||||
double *dx_unaccel,
|
||||
double *dy_unaccel)
|
||||
{
|
||||
if (event->type == CLUTTER_MOTION &&
|
||||
event->motion.flags & CLUTTER_EVENT_FLAG_RELATIVE_MOTION)
|
||||
{
|
||||
if (dx)
|
||||
*dx = event->motion.dx;
|
||||
if (dy)
|
||||
*dy = event->motion.dy;
|
||||
if (dx_unaccel)
|
||||
*dx_unaccel = event->motion.dx_unaccel;
|
||||
if (dy_unaccel)
|
||||
*dy_unaccel = event->motion.dy_unaccel;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -112,17 +112,15 @@ typedef struct _ClutterButtonEvent ClutterButtonEvent;
|
||||
typedef struct _ClutterKeyEvent ClutterKeyEvent;
|
||||
typedef struct _ClutterMotionEvent ClutterMotionEvent;
|
||||
typedef struct _ClutterScrollEvent ClutterScrollEvent;
|
||||
typedef struct _ClutterStageStateEvent ClutterStageStateEvent;
|
||||
typedef struct _ClutterCrossingEvent ClutterCrossingEvent;
|
||||
typedef struct _ClutterTouchEvent ClutterTouchEvent;
|
||||
typedef struct _ClutterTouchpadPinchEvent ClutterTouchpadPinchEvent;
|
||||
typedef struct _ClutterTouchpadSwipeEvent ClutterTouchpadSwipeEvent;
|
||||
typedef struct _ClutterTouchpadHoldEvent ClutterTouchpadHoldEvent;
|
||||
typedef struct _ClutterProximityEvent ClutterProximityEvent;
|
||||
typedef struct _ClutterPadButtonEvent ClutterPadButtonEvent;
|
||||
typedef struct _ClutterPadStripEvent ClutterPadStripEvent;
|
||||
typedef struct _ClutterPadRingEvent ClutterPadRingEvent;
|
||||
typedef struct _ClutterDeviceEvent ClutterDeviceEvent;
|
||||
typedef struct _ClutterIMEvent ClutterIMEvent;
|
||||
|
||||
/**
|
||||
* ClutterAnyEvent:
|
||||
@ -174,7 +172,6 @@ struct _ClutterKeyEvent
|
||||
guint keyval;
|
||||
guint16 hardware_keycode;
|
||||
gunichar unicode_value;
|
||||
uint32_t evdev_code;
|
||||
ClutterInputDevice *device;
|
||||
};
|
||||
|
||||
@ -189,6 +186,8 @@ struct _ClutterKeyEvent
|
||||
* @y: event Y coordinate, relative to the stage
|
||||
* @modifier_state: button modifiers
|
||||
* @button: event button
|
||||
* @click_count: number of button presses within the default time
|
||||
* and radius
|
||||
* @axes: reserved for future use
|
||||
* @device: the device that originated the event. If you want the physical
|
||||
* device the event originated from, use clutter_event_get_source_device()
|
||||
@ -213,9 +212,9 @@ struct _ClutterButtonEvent
|
||||
gfloat y;
|
||||
ClutterModifierType modifier_state;
|
||||
guint32 button;
|
||||
guint click_count;
|
||||
gdouble *axes; /* Future use */
|
||||
ClutterInputDevice *device;
|
||||
uint32_t evdev_code;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -305,12 +304,6 @@ struct _ClutterMotionEvent
|
||||
ClutterModifierType modifier_state;
|
||||
gdouble *axes; /* Future use */
|
||||
ClutterInputDevice *device;
|
||||
|
||||
int64_t time_us;
|
||||
double dx;
|
||||
double dy;
|
||||
double dx_unaccel;
|
||||
double dy_unaccel;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -352,6 +345,32 @@ struct _ClutterScrollEvent
|
||||
ClutterScrollFinishFlags finish_flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterStageStateEvent:
|
||||
* @type: event type
|
||||
* @time: event time
|
||||
* @flags: event flags
|
||||
* @stage: event source stage
|
||||
* @source: event source actor (unused)
|
||||
* @changed_mask: bitwise OR of the changed flags
|
||||
* @new_state: bitwise OR of the current state flags
|
||||
*
|
||||
* Event signalling a change in the #ClutterStage state.
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
struct _ClutterStageStateEvent
|
||||
{
|
||||
ClutterEventType type;
|
||||
guint32 time;
|
||||
ClutterEventFlags flags;
|
||||
ClutterStage *stage;
|
||||
ClutterActor *source; /* XXX: should probably be the stage itself */
|
||||
|
||||
ClutterStageState changed_mask;
|
||||
ClutterStageState new_state;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterTouchEvent:
|
||||
* @type: event type
|
||||
@ -412,10 +431,6 @@ struct _ClutterTouchEvent
|
||||
* @y: the Y coordinate of the pointer, relative to the stage
|
||||
* @dx: movement delta of the pinch focal point in the X axis
|
||||
* @dy: movement delta of the pinch focal point in the Y axis
|
||||
* @dx_unaccel: unaccelerated movement delta of the pinch focal
|
||||
* point in the X axis
|
||||
* @dy_unaccel: unaccelerated movement delta of the pinch focal
|
||||
* point in the Y axis
|
||||
* @angle_delta: angle delta in degrees, clockwise rotations are
|
||||
* represented by positive deltas
|
||||
* @scale: the current scale
|
||||
@ -443,8 +458,6 @@ struct _ClutterTouchpadPinchEvent
|
||||
gfloat y;
|
||||
gfloat dx;
|
||||
gfloat dy;
|
||||
gfloat dx_unaccel;
|
||||
gfloat dy_unaccel;
|
||||
gfloat angle_delta;
|
||||
gfloat scale;
|
||||
guint n_fingers;
|
||||
@ -461,12 +474,8 @@ struct _ClutterTouchpadPinchEvent
|
||||
* @n_fingers: the number of fingers triggering the swipe
|
||||
* @x: the X coordinate of the pointer, relative to the stage
|
||||
* @y: the Y coordinate of the pointer, relative to the stage
|
||||
* @dx: movement delta of the swipe center point in the X axis
|
||||
* @dy: movement delta of the swipe center point in the Y axis
|
||||
* @dx_unaccel: unaccelerated movement delta of the swipe center
|
||||
* point in the X axis
|
||||
* @dy_unaccel: unaccelerated movement delta of the swipe center
|
||||
* point in the Y axis
|
||||
* @dx: movement delta of the pinch focal point in the X axis
|
||||
* @dy: movement delta of the pinch focal point in the Y axis
|
||||
*
|
||||
* Used for touchpad swipe gesture events. The current state of the
|
||||
* gesture will be determined by the @phase field.
|
||||
@ -487,44 +496,6 @@ struct _ClutterTouchpadSwipeEvent
|
||||
gfloat y;
|
||||
gfloat dx;
|
||||
gfloat dy;
|
||||
gfloat dx_unaccel;
|
||||
gfloat dy_unaccel;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterTouchpadHoldEvent
|
||||
* @type: event type
|
||||
* @time: event time
|
||||
* @flags: event flags
|
||||
* @stage: event source stage
|
||||
* @source: event source actor (unused)
|
||||
* @phase: the current phase of the gesture
|
||||
* @n_fingers: the number of fingers triggering the swipe
|
||||
* @x: the X coordinate of the pointer, relative to the stage
|
||||
* @y: the Y coordinate of the pointer, relative to the stage
|
||||
*
|
||||
* Used for touchpad hold gesture events. The current state of the
|
||||
* gesture will be determined by the @phase field.
|
||||
*
|
||||
* A hold gesture starts when the user places one or many fingers on the
|
||||
* touchpad and ends when all fingers are lifted. It is cancelled when the
|
||||
* finger(s) move past a certain threshold.
|
||||
* Unlike swipe and pinch, @phase can only be
|
||||
* CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN, CLUTTER_TOUCHPAD_GESTURE_PHASE_END and
|
||||
* CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL.
|
||||
*/
|
||||
struct _ClutterTouchpadHoldEvent
|
||||
{
|
||||
ClutterEventType type;
|
||||
guint32 time;
|
||||
ClutterEventFlags flags;
|
||||
ClutterStage *stage;
|
||||
ClutterActor *source;
|
||||
|
||||
ClutterTouchpadGesturePhase phase;
|
||||
uint32_t n_fingers;
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
struct _ClutterPadButtonEvent
|
||||
@ -573,31 +544,6 @@ struct _ClutterPadRingEvent
|
||||
guint32 mode;
|
||||
};
|
||||
|
||||
struct _ClutterDeviceEvent
|
||||
{
|
||||
ClutterEventType type;
|
||||
guint32 time;
|
||||
ClutterEventFlags flags;
|
||||
ClutterStage *stage;
|
||||
ClutterActor *source;
|
||||
|
||||
ClutterInputDevice *device;
|
||||
};
|
||||
|
||||
struct _ClutterIMEvent
|
||||
{
|
||||
ClutterEventType type;
|
||||
uint32_t time;
|
||||
ClutterEventFlags flags;
|
||||
ClutterStage *stage;
|
||||
ClutterActor *source;
|
||||
|
||||
char *text;
|
||||
int32_t offset;
|
||||
uint32_t len;
|
||||
ClutterPreeditResetMode mode;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterEvent:
|
||||
*
|
||||
@ -615,17 +561,15 @@ union _ClutterEvent
|
||||
ClutterKeyEvent key;
|
||||
ClutterMotionEvent motion;
|
||||
ClutterScrollEvent scroll;
|
||||
ClutterStageStateEvent stage_state;
|
||||
ClutterCrossingEvent crossing;
|
||||
ClutterTouchEvent touch;
|
||||
ClutterTouchpadPinchEvent touchpad_pinch;
|
||||
ClutterTouchpadSwipeEvent touchpad_swipe;
|
||||
ClutterTouchpadHoldEvent touchpad_hold;
|
||||
ClutterProximityEvent proximity;
|
||||
ClutterPadButtonEvent pad_button;
|
||||
ClutterPadStripEvent pad_strip;
|
||||
ClutterPadRingEvent pad_ring;
|
||||
ClutterDeviceEvent device;
|
||||
ClutterIMEvent im;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -657,6 +601,8 @@ gboolean clutter_events_pending (void);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_get (void);
|
||||
CLUTTER_EXPORT
|
||||
ClutterEvent * clutter_event_peek (void);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_event_put (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
@ -727,6 +673,8 @@ void clutter_event_set_stage (ClutterEvent
|
||||
CLUTTER_EXPORT
|
||||
ClutterStage * clutter_event_get_stage (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
gint clutter_event_get_device_id (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
ClutterInputDeviceType clutter_event_get_device_type (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_event_set_coords (ClutterEvent *event,
|
||||
@ -775,6 +723,8 @@ void clutter_event_set_button (ClutterEvent
|
||||
CLUTTER_EXPORT
|
||||
guint32 clutter_event_get_button (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
guint clutter_event_get_click_count (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_event_set_related (ClutterEvent *event,
|
||||
ClutterActor *actor);
|
||||
CLUTTER_EXPORT
|
||||
@ -823,11 +773,6 @@ void clutter_event_get_gesture_motion_delta (const Clut
|
||||
gdouble *dx,
|
||||
gdouble *dy);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_event_get_gesture_motion_delta_unaccelerated (const ClutterEvent *event,
|
||||
gdouble *dx,
|
||||
gdouble *dy);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterScrollSource clutter_event_get_scroll_source (const ClutterEvent *event);
|
||||
|
||||
@ -842,20 +787,6 @@ gboolean clutter_event_get_pad_event_details (const Clut
|
||||
guint *number,
|
||||
guint *mode,
|
||||
gdouble *value);
|
||||
CLUTTER_EXPORT
|
||||
uint32_t clutter_event_get_event_code (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
int32_t clutter_event_sequence_get_slot (const ClutterEventSequence *sequence);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
int64_t clutter_event_get_time_us (const ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_event_get_relative_motion (const ClutterEvent *event,
|
||||
double *dx,
|
||||
double *dy,
|
||||
double *dx_unaccel,
|
||||
double *dy_unaccel);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -64,13 +64,16 @@ clutter_features_from_cogl (void)
|
||||
|
||||
clutter_flags |= CLUTTER_FEATURE_SHADERS_GLSL;
|
||||
|
||||
clutter_flags |= CLUTTER_FEATURE_OFFSCREEN;
|
||||
|
||||
return clutter_flags;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_feature_init (ClutterMainContext *context,
|
||||
GError **error)
|
||||
_clutter_feature_init (GError **error)
|
||||
{
|
||||
ClutterMainContext *context;
|
||||
|
||||
CLUTTER_NOTE (MISC, "checking features");
|
||||
|
||||
if (!__features)
|
||||
@ -83,11 +86,14 @@ clutter_feature_init (ClutterMainContext *context,
|
||||
if (__features->features_set)
|
||||
return TRUE;
|
||||
|
||||
context = _clutter_context_get_default ();
|
||||
|
||||
/* makes sure we have a GL context; if we have, this is a no-op */
|
||||
if (!_clutter_backend_create_context (context->backend, error))
|
||||
return FALSE;
|
||||
|
||||
__features->flags = clutter_features_from_cogl ();
|
||||
__features->flags = (clutter_features_from_cogl ()
|
||||
| _clutter_backend_get_features (context->backend));
|
||||
|
||||
__features->features_set = TRUE;
|
||||
|
||||
|
@ -139,11 +139,7 @@ clutter_fixed_layout_allocate (ClutterLayoutManager *manager,
|
||||
child != NULL;
|
||||
child = clutter_actor_get_next_sibling (child))
|
||||
{
|
||||
float x = 0.f;
|
||||
float y = 0.f;
|
||||
|
||||
clutter_actor_get_fixed_position (child, &x, &y);
|
||||
clutter_actor_allocate_preferred_size (child, x, y);
|
||||
clutter_actor_allocate_preferred_size (child);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -913,7 +913,7 @@ clutter_flow_layout_class_init (ClutterFlowLayoutClass *klass)
|
||||
* ClutterFlowLayout:orientation:
|
||||
*
|
||||
* The orientation of the #ClutterFlowLayout. The children
|
||||
* of the layout will be laid out following the orientation.
|
||||
* of the layout will be layed out following the orientation.
|
||||
*
|
||||
* This property also controls the overflowing directions
|
||||
*
|
||||
|
@ -1,843 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter/clutter-frame-clock.h"
|
||||
|
||||
#include "clutter/clutter-debug.h"
|
||||
#include "clutter/clutter-main.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#include "clutter/clutter-timeline-private.h"
|
||||
#include "cogl/cogl-trace.h"
|
||||
|
||||
enum
|
||||
{
|
||||
DESTROY,
|
||||
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
static guint signals[N_SIGNALS];
|
||||
|
||||
/* An estimate queue holds several int64_t values. Adding a new value to the
|
||||
* queue overwrites the oldest value.
|
||||
*/
|
||||
#define ESTIMATE_QUEUE_LENGTH 16
|
||||
|
||||
typedef struct _EstimateQueue
|
||||
{
|
||||
int64_t values[ESTIMATE_QUEUE_LENGTH];
|
||||
int next_index;
|
||||
} EstimateQueue;
|
||||
|
||||
/* When heuristic render time is off,
|
||||
* wait 2ms after vblank before starting to draw next frame.
|
||||
*/
|
||||
#define SYNC_DELAY_FALLBACK_US ms2us (2)
|
||||
|
||||
typedef struct _ClutterFrameListener
|
||||
{
|
||||
const ClutterFrameListenerIface *iface;
|
||||
gpointer user_data;
|
||||
} ClutterFrameListener;
|
||||
|
||||
typedef struct _ClutterClockSource
|
||||
{
|
||||
GSource source;
|
||||
|
||||
ClutterFrameClock *frame_clock;
|
||||
} ClutterClockSource;
|
||||
|
||||
typedef enum _ClutterFrameClockState
|
||||
{
|
||||
CLUTTER_FRAME_CLOCK_STATE_INIT,
|
||||
CLUTTER_FRAME_CLOCK_STATE_IDLE,
|
||||
CLUTTER_FRAME_CLOCK_STATE_SCHEDULED,
|
||||
CLUTTER_FRAME_CLOCK_STATE_DISPATCHING,
|
||||
CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED,
|
||||
} ClutterFrameClockState;
|
||||
|
||||
struct _ClutterFrameClock
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
float refresh_rate;
|
||||
int64_t refresh_interval_us;
|
||||
ClutterFrameListener listener;
|
||||
|
||||
GSource *source;
|
||||
|
||||
int64_t frame_count;
|
||||
|
||||
ClutterFrameClockState state;
|
||||
int64_t last_dispatch_time_us;
|
||||
int64_t last_dispatch_lateness_us;
|
||||
int64_t last_presentation_time_us;
|
||||
|
||||
gboolean is_next_presentation_time_valid;
|
||||
int64_t next_presentation_time_us;
|
||||
|
||||
/* Buffer must be submitted to KMS and GPU rendering must be finished
|
||||
* this amount of time before the next presentation time.
|
||||
*/
|
||||
int64_t vblank_duration_us;
|
||||
/* Last KMS buffer submission time. */
|
||||
int64_t last_flip_time_us;
|
||||
|
||||
/* Last few durations between dispatch start and buffer swap. */
|
||||
EstimateQueue dispatch_to_swap_us;
|
||||
/* Last few durations between buffer swap and GPU rendering finish. */
|
||||
EstimateQueue swap_to_rendering_done_us;
|
||||
/* Last few durations between buffer swap and KMS submission. */
|
||||
EstimateQueue swap_to_flip_us;
|
||||
/* If we got new measurements last frame. */
|
||||
gboolean got_measurements_last_frame;
|
||||
|
||||
gboolean pending_reschedule;
|
||||
gboolean pending_reschedule_now;
|
||||
|
||||
int inhibit_count;
|
||||
|
||||
GList *timelines;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ClutterFrameClock, clutter_frame_clock,
|
||||
G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
estimate_queue_add_value (EstimateQueue *queue,
|
||||
int64_t value)
|
||||
{
|
||||
queue->values[queue->next_index] = value;
|
||||
queue->next_index = (queue->next_index + 1) % ESTIMATE_QUEUE_LENGTH;
|
||||
}
|
||||
|
||||
float
|
||||
clutter_frame_clock_get_refresh_rate (ClutterFrameClock *frame_clock)
|
||||
{
|
||||
return frame_clock->refresh_rate;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_frame_clock_set_refresh_rate (ClutterFrameClock *frame_clock,
|
||||
float refresh_rate)
|
||||
{
|
||||
frame_clock->refresh_rate = refresh_rate;
|
||||
frame_clock->refresh_interval_us =
|
||||
(int64_t) (0.5 + G_USEC_PER_SEC / refresh_rate);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_frame_clock_add_timeline (ClutterFrameClock *frame_clock,
|
||||
ClutterTimeline *timeline)
|
||||
{
|
||||
gboolean is_first;
|
||||
|
||||
if (g_list_find (frame_clock->timelines, timeline))
|
||||
return;
|
||||
|
||||
is_first = !frame_clock->timelines;
|
||||
|
||||
frame_clock->timelines = g_list_prepend (frame_clock->timelines, timeline);
|
||||
|
||||
if (is_first)
|
||||
clutter_frame_clock_schedule_update (frame_clock);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_frame_clock_remove_timeline (ClutterFrameClock *frame_clock,
|
||||
ClutterTimeline *timeline)
|
||||
{
|
||||
frame_clock->timelines = g_list_remove (frame_clock->timelines, timeline);
|
||||
}
|
||||
|
||||
static void
|
||||
advance_timelines (ClutterFrameClock *frame_clock,
|
||||
int64_t time_us)
|
||||
{
|
||||
GList *timelines;
|
||||
GList *l;
|
||||
|
||||
/* we protect ourselves from timelines being removed during
|
||||
* the advancement by other timelines by copying the list of
|
||||
* timelines, taking a reference on them, iterating over the
|
||||
* copied list and then releasing the reference.
|
||||
*
|
||||
* we cannot simply take a reference on the timelines and still
|
||||
* use the list held by the master clock because the do_tick()
|
||||
* might result in the creation of a new timeline, which gets
|
||||
* added at the end of the list with no reference increase and
|
||||
* thus gets disposed at the end of the iteration.
|
||||
*
|
||||
* this implies that a newly added timeline will not be advanced
|
||||
* by this clock iteration, which is perfectly fine since we're
|
||||
* in its first cycle.
|
||||
*
|
||||
* we also cannot steal the frame clock timelines list because
|
||||
* a timeline might be removed as the direct result of do_tick()
|
||||
* and remove_timeline() would not find the timeline, failing
|
||||
* and leaving a dangling pointer behind.
|
||||
*/
|
||||
|
||||
timelines = g_list_copy (frame_clock->timelines);
|
||||
g_list_foreach (timelines, (GFunc) g_object_ref, NULL);
|
||||
|
||||
for (l = timelines; l; l = l->next)
|
||||
{
|
||||
ClutterTimeline *timeline = l->data;
|
||||
|
||||
_clutter_timeline_do_tick (timeline, time_us / 1000);
|
||||
}
|
||||
|
||||
g_list_free_full (timelines, g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_reschedule_update (ClutterFrameClock *frame_clock)
|
||||
{
|
||||
if (frame_clock->pending_reschedule ||
|
||||
frame_clock->timelines)
|
||||
{
|
||||
frame_clock->pending_reschedule = FALSE;
|
||||
|
||||
if (frame_clock->pending_reschedule_now)
|
||||
{
|
||||
frame_clock->pending_reschedule_now = FALSE;
|
||||
clutter_frame_clock_schedule_update_now (frame_clock);
|
||||
}
|
||||
else
|
||||
{
|
||||
clutter_frame_clock_schedule_update (frame_clock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock,
|
||||
ClutterFrameInfo *frame_info)
|
||||
{
|
||||
frame_clock->last_presentation_time_us = frame_info->presentation_time;
|
||||
|
||||
frame_clock->got_measurements_last_frame = FALSE;
|
||||
|
||||
if (frame_info->cpu_time_before_buffer_swap_us != 0 &&
|
||||
frame_info->gpu_rendering_duration_ns != 0)
|
||||
{
|
||||
int64_t dispatch_to_swap_us, swap_to_rendering_done_us, swap_to_flip_us;
|
||||
|
||||
dispatch_to_swap_us =
|
||||
frame_info->cpu_time_before_buffer_swap_us -
|
||||
frame_clock->last_dispatch_time_us;
|
||||
swap_to_rendering_done_us =
|
||||
frame_info->gpu_rendering_duration_ns / 1000;
|
||||
swap_to_flip_us =
|
||||
frame_clock->last_flip_time_us -
|
||||
frame_info->cpu_time_before_buffer_swap_us;
|
||||
|
||||
CLUTTER_NOTE (FRAME_TIMINGS,
|
||||
"dispatch2swap %ld µs, swap2render %ld µs, swap2flip %ld µs",
|
||||
dispatch_to_swap_us,
|
||||
swap_to_rendering_done_us,
|
||||
swap_to_flip_us);
|
||||
|
||||
estimate_queue_add_value (&frame_clock->dispatch_to_swap_us,
|
||||
dispatch_to_swap_us);
|
||||
estimate_queue_add_value (&frame_clock->swap_to_rendering_done_us,
|
||||
swap_to_rendering_done_us);
|
||||
estimate_queue_add_value (&frame_clock->swap_to_flip_us,
|
||||
swap_to_flip_us);
|
||||
|
||||
frame_clock->got_measurements_last_frame = TRUE;
|
||||
}
|
||||
|
||||
if (frame_info->refresh_rate > 1)
|
||||
{
|
||||
clutter_frame_clock_set_refresh_rate (frame_clock,
|
||||
frame_info->refresh_rate);
|
||||
}
|
||||
|
||||
switch (frame_clock->state)
|
||||
{
|
||||
case CLUTTER_FRAME_CLOCK_STATE_INIT:
|
||||
case CLUTTER_FRAME_CLOCK_STATE_IDLE:
|
||||
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
||||
g_warn_if_reached ();
|
||||
break;
|
||||
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
||||
case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED:
|
||||
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_IDLE;
|
||||
maybe_reschedule_update (frame_clock);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
clutter_frame_clock_notify_ready (ClutterFrameClock *frame_clock)
|
||||
{
|
||||
switch (frame_clock->state)
|
||||
{
|
||||
case CLUTTER_FRAME_CLOCK_STATE_INIT:
|
||||
case CLUTTER_FRAME_CLOCK_STATE_IDLE:
|
||||
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
||||
g_warn_if_reached ();
|
||||
break;
|
||||
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
||||
case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED:
|
||||
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_IDLE;
|
||||
maybe_reschedule_update (frame_clock);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int64_t
|
||||
clutter_frame_clock_compute_max_render_time_us (ClutterFrameClock *frame_clock)
|
||||
{
|
||||
int64_t refresh_interval_us;
|
||||
int64_t max_dispatch_to_swap_us = 0;
|
||||
int64_t max_swap_to_rendering_done_us = 0;
|
||||
int64_t max_swap_to_flip_us = 0;
|
||||
int64_t max_render_time_us;
|
||||
int i;
|
||||
|
||||
refresh_interval_us =
|
||||
(int64_t) (0.5 + G_USEC_PER_SEC / frame_clock->refresh_rate);
|
||||
|
||||
if (!frame_clock->got_measurements_last_frame ||
|
||||
G_UNLIKELY (clutter_paint_debug_flags &
|
||||
CLUTTER_DEBUG_DISABLE_DYNAMIC_MAX_RENDER_TIME))
|
||||
return refresh_interval_us - SYNC_DELAY_FALLBACK_US;
|
||||
|
||||
for (i = 0; i < ESTIMATE_QUEUE_LENGTH; ++i)
|
||||
{
|
||||
max_dispatch_to_swap_us =
|
||||
MAX (max_dispatch_to_swap_us,
|
||||
frame_clock->dispatch_to_swap_us.values[i]);
|
||||
max_swap_to_rendering_done_us =
|
||||
MAX (max_swap_to_rendering_done_us,
|
||||
frame_clock->swap_to_rendering_done_us.values[i]);
|
||||
max_swap_to_flip_us =
|
||||
MAX (max_swap_to_flip_us,
|
||||
frame_clock->swap_to_flip_us.values[i]);
|
||||
}
|
||||
|
||||
/* Max render time shows how early the frame clock needs to be dispatched
|
||||
* to make it to the predicted next presentation time. It is composed of:
|
||||
* - An estimate of duration from dispatch start to buffer swap.
|
||||
* - Maximum between estimates of duration from buffer swap to GPU rendering
|
||||
* finish and duration from buffer swap to buffer submission to KMS. This
|
||||
* is because both of these things need to happen before the vblank, and
|
||||
* they are done in parallel.
|
||||
* - Duration of the vblank.
|
||||
* - A constant to account for variations in the above estimates.
|
||||
*/
|
||||
max_render_time_us =
|
||||
max_dispatch_to_swap_us +
|
||||
MAX (max_swap_to_rendering_done_us, max_swap_to_flip_us) +
|
||||
frame_clock->vblank_duration_us +
|
||||
clutter_max_render_time_constant_us;
|
||||
|
||||
max_render_time_us = CLAMP (max_render_time_us, 0, refresh_interval_us);
|
||||
|
||||
return max_render_time_us;
|
||||
}
|
||||
|
||||
static void
|
||||
calculate_next_update_time_us (ClutterFrameClock *frame_clock,
|
||||
int64_t *out_next_update_time_us,
|
||||
int64_t *out_next_presentation_time_us)
|
||||
{
|
||||
int64_t last_presentation_time_us;
|
||||
int64_t now_us;
|
||||
int64_t refresh_interval_us;
|
||||
int64_t min_render_time_allowed_us;
|
||||
int64_t max_render_time_allowed_us;
|
||||
int64_t last_next_presentation_time_us;
|
||||
int64_t time_since_last_next_presentation_time_us;
|
||||
int64_t next_presentation_time_us;
|
||||
int64_t next_update_time_us;
|
||||
|
||||
now_us = g_get_monotonic_time ();
|
||||
|
||||
refresh_interval_us = frame_clock->refresh_interval_us;
|
||||
|
||||
if (frame_clock->last_presentation_time_us == 0)
|
||||
{
|
||||
*out_next_update_time_us =
|
||||
frame_clock->last_dispatch_time_us ?
|
||||
((frame_clock->last_dispatch_time_us -
|
||||
frame_clock->last_dispatch_lateness_us) + refresh_interval_us) :
|
||||
now_us;
|
||||
|
||||
*out_next_presentation_time_us = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
min_render_time_allowed_us = refresh_interval_us / 2;
|
||||
max_render_time_allowed_us =
|
||||
clutter_frame_clock_compute_max_render_time_us (frame_clock);
|
||||
|
||||
if (min_render_time_allowed_us > max_render_time_allowed_us)
|
||||
min_render_time_allowed_us = max_render_time_allowed_us;
|
||||
|
||||
/*
|
||||
* The common case is that the next presentation happens 1 refresh interval
|
||||
* after the last presentation:
|
||||
*
|
||||
* last_presentation_time_us
|
||||
* / next_presentation_time_us
|
||||
* / /
|
||||
* / /
|
||||
* |--|--o----|-------|--> presentation times
|
||||
* | | \ |
|
||||
* | | now_us
|
||||
* | \______/
|
||||
* | refresh_interval_us
|
||||
* |
|
||||
* 0
|
||||
*
|
||||
*/
|
||||
last_presentation_time_us = frame_clock->last_presentation_time_us;
|
||||
next_presentation_time_us = last_presentation_time_us + refresh_interval_us;
|
||||
|
||||
/*
|
||||
* However, the last presentation could have happened more than a frame ago.
|
||||
* For example, due to idling (nothing on screen changed, so no need to
|
||||
* redraw) or due to frames missing deadlines (GPU busy with heavy rendering).
|
||||
* The following code adjusts next_presentation_time_us to be in the future,
|
||||
* but still aligned to display presentation times. Instead of
|
||||
* next presentation = last presentation + 1 * refresh interval, it will be
|
||||
* next presentation = last presentation + N * refresh interval.
|
||||
*/
|
||||
if (next_presentation_time_us < now_us)
|
||||
{
|
||||
int64_t presentation_phase_us;
|
||||
int64_t current_phase_us;
|
||||
int64_t current_refresh_interval_start_us;
|
||||
|
||||
/*
|
||||
* Let's say we're just past next_presentation_time_us.
|
||||
*
|
||||
* First, we compute presentation_phase_us. Real presentation times don't
|
||||
* have to be exact multiples of refresh_interval_us and
|
||||
* presentation_phase_us represents this difference. Next, we compute
|
||||
* current phase and the refresh interval start corresponding to now_us.
|
||||
* Finally, add presentation_phase_us and a refresh interval to get the
|
||||
* next presentation after now_us.
|
||||
*
|
||||
* last_presentation_time_us
|
||||
* / next_presentation_time_us
|
||||
* / / now_us
|
||||
* / / / new next_presentation_time_us
|
||||
* |--|-------|---o---|-------|--> presentation times
|
||||
* | __|
|
||||
* | |presentation_phase_us
|
||||
* | |
|
||||
* | | now_us - presentation_phase_us
|
||||
* | | /
|
||||
* |-------|---o---|-------|-----> integer multiples of refresh_interval_us
|
||||
* | \__/
|
||||
* | |current_phase_us
|
||||
* | \
|
||||
* | current_refresh_interval_start_us
|
||||
* 0
|
||||
*
|
||||
*/
|
||||
|
||||
presentation_phase_us = last_presentation_time_us % refresh_interval_us;
|
||||
current_phase_us = (now_us - presentation_phase_us) % refresh_interval_us;
|
||||
current_refresh_interval_start_us =
|
||||
now_us - presentation_phase_us - current_phase_us;
|
||||
|
||||
next_presentation_time_us =
|
||||
current_refresh_interval_start_us +
|
||||
presentation_phase_us +
|
||||
refresh_interval_us;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip one interval if we got an early presented event.
|
||||
*
|
||||
* last frame this was last_presentation_time
|
||||
* / frame_clock->next_presentation_time_us
|
||||
* / /
|
||||
* |---|-o-----|-x----->
|
||||
* | \
|
||||
* \ next_presentation_time_us is thus right after the last one
|
||||
* but got an unexpected early presentation
|
||||
* \_/
|
||||
* time_since_last_next_presentation_time_us
|
||||
*
|
||||
*/
|
||||
last_next_presentation_time_us = frame_clock->next_presentation_time_us;
|
||||
time_since_last_next_presentation_time_us =
|
||||
next_presentation_time_us - last_next_presentation_time_us;
|
||||
if (frame_clock->is_next_presentation_time_valid &&
|
||||
time_since_last_next_presentation_time_us < (refresh_interval_us / 2))
|
||||
{
|
||||
next_presentation_time_us =
|
||||
frame_clock->next_presentation_time_us + refresh_interval_us;
|
||||
}
|
||||
|
||||
while (next_presentation_time_us < now_us + min_render_time_allowed_us)
|
||||
next_presentation_time_us += refresh_interval_us;
|
||||
|
||||
next_update_time_us = next_presentation_time_us - max_render_time_allowed_us;
|
||||
|
||||
*out_next_update_time_us = next_update_time_us;
|
||||
*out_next_presentation_time_us = next_presentation_time_us;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_frame_clock_inhibit (ClutterFrameClock *frame_clock)
|
||||
{
|
||||
frame_clock->inhibit_count++;
|
||||
|
||||
if (frame_clock->inhibit_count == 1)
|
||||
{
|
||||
switch (frame_clock->state)
|
||||
{
|
||||
case CLUTTER_FRAME_CLOCK_STATE_INIT:
|
||||
case CLUTTER_FRAME_CLOCK_STATE_IDLE:
|
||||
break;
|
||||
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
||||
frame_clock->pending_reschedule = TRUE;
|
||||
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_IDLE;
|
||||
break;
|
||||
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
||||
case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED:
|
||||
break;
|
||||
}
|
||||
|
||||
g_source_set_ready_time (frame_clock->source, -1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
clutter_frame_clock_uninhibit (ClutterFrameClock *frame_clock)
|
||||
{
|
||||
g_return_if_fail (frame_clock->inhibit_count > 0);
|
||||
|
||||
frame_clock->inhibit_count--;
|
||||
|
||||
if (frame_clock->inhibit_count == 0)
|
||||
maybe_reschedule_update (frame_clock);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock)
|
||||
{
|
||||
int64_t next_update_time_us = -1;
|
||||
|
||||
if (frame_clock->inhibit_count > 0)
|
||||
{
|
||||
frame_clock->pending_reschedule = TRUE;
|
||||
frame_clock->pending_reschedule_now = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (frame_clock->state)
|
||||
{
|
||||
case CLUTTER_FRAME_CLOCK_STATE_INIT:
|
||||
case CLUTTER_FRAME_CLOCK_STATE_IDLE:
|
||||
next_update_time_us = g_get_monotonic_time ();
|
||||
break;
|
||||
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
||||
return;
|
||||
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
||||
case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED:
|
||||
frame_clock->pending_reschedule = TRUE;
|
||||
frame_clock->pending_reschedule_now = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
g_warn_if_fail (next_update_time_us != -1);
|
||||
|
||||
g_source_set_ready_time (frame_clock->source, next_update_time_us);
|
||||
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_SCHEDULED;
|
||||
frame_clock->is_next_presentation_time_valid = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock)
|
||||
{
|
||||
int64_t next_update_time_us = -1;
|
||||
|
||||
if (frame_clock->inhibit_count > 0)
|
||||
{
|
||||
frame_clock->pending_reschedule = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (frame_clock->state)
|
||||
{
|
||||
case CLUTTER_FRAME_CLOCK_STATE_INIT:
|
||||
next_update_time_us = g_get_monotonic_time ();
|
||||
break;
|
||||
case CLUTTER_FRAME_CLOCK_STATE_IDLE:
|
||||
calculate_next_update_time_us (frame_clock,
|
||||
&next_update_time_us,
|
||||
&frame_clock->next_presentation_time_us);
|
||||
frame_clock->is_next_presentation_time_valid =
|
||||
(frame_clock->next_presentation_time_us != 0);
|
||||
break;
|
||||
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
||||
return;
|
||||
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
||||
case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED:
|
||||
frame_clock->pending_reschedule = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
g_warn_if_fail (next_update_time_us != -1);
|
||||
|
||||
g_source_set_ready_time (frame_clock->source, next_update_time_us);
|
||||
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_SCHEDULED;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock,
|
||||
int64_t time_us)
|
||||
{
|
||||
int64_t frame_count;
|
||||
ClutterFrameResult result;
|
||||
int64_t ideal_dispatch_time_us, lateness_us;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (ClutterFrameClockDispatch, "Frame Clock (dispatch)");
|
||||
|
||||
ideal_dispatch_time_us = (frame_clock->last_dispatch_time_us -
|
||||
frame_clock->last_dispatch_lateness_us) +
|
||||
frame_clock->refresh_interval_us;
|
||||
|
||||
lateness_us = time_us - ideal_dispatch_time_us;
|
||||
if (lateness_us < 0 || lateness_us >= frame_clock->refresh_interval_us)
|
||||
frame_clock->last_dispatch_lateness_us = 0;
|
||||
else
|
||||
frame_clock->last_dispatch_lateness_us = lateness_us;
|
||||
|
||||
frame_clock->last_dispatch_time_us = time_us;
|
||||
g_source_set_ready_time (frame_clock->source, -1);
|
||||
|
||||
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_DISPATCHING;
|
||||
|
||||
frame_count = frame_clock->frame_count++;
|
||||
|
||||
COGL_TRACE_BEGIN (ClutterFrameClockEvents, "Frame Clock (before frame)");
|
||||
if (frame_clock->listener.iface->before_frame)
|
||||
{
|
||||
frame_clock->listener.iface->before_frame (frame_clock,
|
||||
frame_count,
|
||||
frame_clock->listener.user_data);
|
||||
}
|
||||
COGL_TRACE_END (ClutterFrameClockEvents);
|
||||
|
||||
COGL_TRACE_BEGIN (ClutterFrameClockTimelines, "Frame Clock (timelines)");
|
||||
advance_timelines (frame_clock, time_us);
|
||||
COGL_TRACE_END (ClutterFrameClockTimelines);
|
||||
|
||||
COGL_TRACE_BEGIN (ClutterFrameClockFrame, "Frame Clock (frame)");
|
||||
result = frame_clock->listener.iface->frame (frame_clock,
|
||||
frame_count,
|
||||
time_us,
|
||||
frame_clock->listener.user_data);
|
||||
COGL_TRACE_END (ClutterFrameClockFrame);
|
||||
|
||||
switch (frame_clock->state)
|
||||
{
|
||||
case CLUTTER_FRAME_CLOCK_STATE_INIT:
|
||||
case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED:
|
||||
g_warn_if_reached ();
|
||||
break;
|
||||
case CLUTTER_FRAME_CLOCK_STATE_IDLE:
|
||||
case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED:
|
||||
break;
|
||||
case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING:
|
||||
switch (result)
|
||||
{
|
||||
case CLUTTER_FRAME_RESULT_PENDING_PRESENTED:
|
||||
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED;
|
||||
break;
|
||||
case CLUTTER_FRAME_RESULT_IDLE:
|
||||
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_IDLE;
|
||||
maybe_reschedule_update (frame_clock);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
frame_clock_source_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterClockSource *clock_source = (ClutterClockSource *) source;
|
||||
ClutterFrameClock *frame_clock = clock_source->frame_clock;
|
||||
int64_t dispatch_time_us;
|
||||
|
||||
dispatch_time_us = g_source_get_time (source);
|
||||
clutter_frame_clock_dispatch (frame_clock, dispatch_time_us);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_frame_clock_record_flip_time (ClutterFrameClock *frame_clock,
|
||||
int64_t flip_time_us)
|
||||
{
|
||||
frame_clock->last_flip_time_us = flip_time_us;
|
||||
}
|
||||
|
||||
GString *
|
||||
clutter_frame_clock_get_max_render_time_debug_info (ClutterFrameClock *frame_clock)
|
||||
{
|
||||
int64_t max_dispatch_to_swap_us = 0;
|
||||
int64_t max_swap_to_rendering_done_us = 0;
|
||||
int64_t max_swap_to_flip_us = 0;
|
||||
int i;
|
||||
GString *string;
|
||||
|
||||
string = g_string_new (NULL);
|
||||
g_string_append_printf (string, "Max render time: %ld µs",
|
||||
clutter_frame_clock_compute_max_render_time_us (frame_clock));
|
||||
|
||||
if (frame_clock->got_measurements_last_frame)
|
||||
g_string_append_printf (string, " =");
|
||||
else
|
||||
g_string_append_printf (string, " (no measurements last frame)");
|
||||
|
||||
for (i = 0; i < ESTIMATE_QUEUE_LENGTH; ++i)
|
||||
{
|
||||
max_dispatch_to_swap_us =
|
||||
MAX (max_dispatch_to_swap_us,
|
||||
frame_clock->dispatch_to_swap_us.values[i]);
|
||||
max_swap_to_rendering_done_us =
|
||||
MAX (max_swap_to_rendering_done_us,
|
||||
frame_clock->swap_to_rendering_done_us.values[i]);
|
||||
max_swap_to_flip_us =
|
||||
MAX (max_swap_to_flip_us,
|
||||
frame_clock->swap_to_flip_us.values[i]);
|
||||
}
|
||||
|
||||
g_string_append_printf (string, "\nVblank duration: %ld µs +",
|
||||
frame_clock->vblank_duration_us);
|
||||
g_string_append_printf (string, "\nDispatch to swap: %ld µs +",
|
||||
max_dispatch_to_swap_us);
|
||||
g_string_append_printf (string, "\nmax(Swap to rendering done: %ld µs,",
|
||||
max_swap_to_rendering_done_us);
|
||||
g_string_append_printf (string, "\nSwap to flip: %ld µs) +",
|
||||
max_swap_to_flip_us);
|
||||
g_string_append_printf (string, "\nConstant: %d µs",
|
||||
clutter_max_render_time_constant_us);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
static GSourceFuncs frame_clock_source_funcs = {
|
||||
NULL,
|
||||
NULL,
|
||||
frame_clock_source_dispatch,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void
|
||||
init_frame_clock_source (ClutterFrameClock *frame_clock)
|
||||
{
|
||||
GSource *source;
|
||||
ClutterClockSource *clock_source;
|
||||
g_autofree char *name = NULL;
|
||||
|
||||
source = g_source_new (&frame_clock_source_funcs, sizeof (ClutterClockSource));
|
||||
clock_source = (ClutterClockSource *) source;
|
||||
|
||||
name = g_strdup_printf ("Clutter frame clock (%p)", frame_clock);
|
||||
g_source_set_name (source, name);
|
||||
g_source_set_priority (source, CLUTTER_PRIORITY_REDRAW);
|
||||
g_source_set_can_recurse (source, FALSE);
|
||||
clock_source->frame_clock = frame_clock;
|
||||
|
||||
frame_clock->source = source;
|
||||
g_source_attach (source, NULL);
|
||||
}
|
||||
|
||||
ClutterFrameClock *
|
||||
clutter_frame_clock_new (float refresh_rate,
|
||||
int64_t vblank_duration_us,
|
||||
const ClutterFrameListenerIface *iface,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterFrameClock *frame_clock;
|
||||
|
||||
g_assert_cmpfloat (refresh_rate, >, 0.0);
|
||||
|
||||
frame_clock = g_object_new (CLUTTER_TYPE_FRAME_CLOCK, NULL);
|
||||
|
||||
frame_clock->listener.iface = iface;
|
||||
frame_clock->listener.user_data = user_data;
|
||||
|
||||
init_frame_clock_source (frame_clock);
|
||||
|
||||
clutter_frame_clock_set_refresh_rate (frame_clock, refresh_rate);
|
||||
frame_clock->vblank_duration_us = vblank_duration_us;
|
||||
|
||||
return frame_clock;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_frame_clock_destroy (ClutterFrameClock *frame_clock)
|
||||
{
|
||||
g_object_run_dispose (G_OBJECT (frame_clock));
|
||||
g_object_unref (frame_clock);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_frame_clock_dispose (GObject *object)
|
||||
{
|
||||
ClutterFrameClock *frame_clock = CLUTTER_FRAME_CLOCK (object);
|
||||
|
||||
if (frame_clock->source)
|
||||
{
|
||||
g_signal_emit (frame_clock, signals[DESTROY], 0);
|
||||
g_source_destroy (frame_clock->source);
|
||||
g_clear_pointer (&frame_clock->source, g_source_unref);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (clutter_frame_clock_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_frame_clock_init (ClutterFrameClock *frame_clock)
|
||||
{
|
||||
frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_INIT;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_frame_clock_class_init (ClutterFrameClockClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = clutter_frame_clock_dispose;
|
||||
|
||||
signals[DESTROY] =
|
||||
g_signal_new (I_("destroy"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CLUTTER_FRAME_CLOCK_H
|
||||
#define CLUTTER_FRAME_CLOCK_H
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "clutter/clutter-types.h"
|
||||
|
||||
typedef enum _ClutterFrameResult
|
||||
{
|
||||
CLUTTER_FRAME_RESULT_PENDING_PRESENTED,
|
||||
CLUTTER_FRAME_RESULT_IDLE,
|
||||
} ClutterFrameResult;
|
||||
|
||||
#define CLUTTER_TYPE_FRAME_CLOCK (clutter_frame_clock_get_type ())
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_FINAL_TYPE (ClutterFrameClock, clutter_frame_clock,
|
||||
CLUTTER, FRAME_CLOCK,
|
||||
GObject)
|
||||
|
||||
/**
|
||||
* ClutterFrameListenerIface: (skip)
|
||||
*/
|
||||
typedef struct _ClutterFrameListenerIface
|
||||
{
|
||||
void (* before_frame) (ClutterFrameClock *frame_clock,
|
||||
int64_t frame_count,
|
||||
gpointer user_data);
|
||||
ClutterFrameResult (* frame) (ClutterFrameClock *frame_clock,
|
||||
int64_t frame_count,
|
||||
int64_t time_us,
|
||||
gpointer user_data);
|
||||
} ClutterFrameListenerIface;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterFrameClock * clutter_frame_clock_new (float refresh_rate,
|
||||
int64_t vblank_duration_us,
|
||||
const ClutterFrameListenerIface *iface,
|
||||
gpointer user_data);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_frame_clock_destroy (ClutterFrameClock *frame_clock);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock,
|
||||
ClutterFrameInfo *frame_info);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_frame_clock_notify_ready (ClutterFrameClock *frame_clock);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_frame_clock_inhibit (ClutterFrameClock *frame_clock);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_frame_clock_uninhibit (ClutterFrameClock *frame_clock);
|
||||
|
||||
void clutter_frame_clock_add_timeline (ClutterFrameClock *frame_clock,
|
||||
ClutterTimeline *timeline);
|
||||
|
||||
void clutter_frame_clock_remove_timeline (ClutterFrameClock *frame_clock,
|
||||
ClutterTimeline *timeline);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
float clutter_frame_clock_get_refresh_rate (ClutterFrameClock *frame_clock);
|
||||
|
||||
void clutter_frame_clock_record_flip_time (ClutterFrameClock *frame_clock,
|
||||
int64_t flip_time_us);
|
||||
|
||||
GString * clutter_frame_clock_get_max_render_time_debug_info (ClutterFrameClock *frame_clock);
|
||||
|
||||
#endif /* CLUTTER_FRAME_CLOCK_H */
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CLUTTER_FRAME_PRIVATE_H
|
||||
#define CLUTTER_FRAME_PRIVATE_H
|
||||
|
||||
#include "clutter/clutter-frame.h"
|
||||
|
||||
struct _ClutterFrame
|
||||
{
|
||||
gboolean has_result;
|
||||
ClutterFrameResult result;
|
||||
};
|
||||
|
||||
#define CLUTTER_FRAME_INIT ((ClutterFrame) { 0 })
|
||||
|
||||
ClutterFrameResult clutter_frame_get_result (ClutterFrame *frame);
|
||||
|
||||
#endif /* CLUTTER_FRAME_PRIVATE_H */
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "clutter/clutter-frame-private.h"
|
||||
|
||||
ClutterFrameResult
|
||||
clutter_frame_get_result (ClutterFrame *frame)
|
||||
{
|
||||
g_return_val_if_fail (frame->has_result, CLUTTER_FRAME_RESULT_IDLE);
|
||||
|
||||
return frame->result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_frame_has_result (ClutterFrame *frame)
|
||||
{
|
||||
return frame->has_result;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_frame_set_result (ClutterFrame *frame,
|
||||
ClutterFrameResult result)
|
||||
{
|
||||
g_warn_if_fail (!frame->has_result);
|
||||
|
||||
frame->result = result;
|
||||
frame->has_result = TRUE;
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Red Hat Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CLUTTER_FRAME_H
|
||||
#define CLUTTER_FRAME_H
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "clutter/clutter-frame-clock.h"
|
||||
|
||||
typedef struct _ClutterFrame ClutterFrame;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_frame_set_result (ClutterFrame *frame,
|
||||
ClutterFrameResult result);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_frame_has_result (ClutterFrame *frame);
|
||||
|
||||
#endif /* CLUTTER_FRAME_H */
|
@ -118,6 +118,9 @@ struct _ClutterGestureActionPrivate
|
||||
gint requested_nb_points;
|
||||
GArray *points;
|
||||
|
||||
gulong actor_capture_id;
|
||||
gulong stage_capture_id;
|
||||
|
||||
ClutterGestureTriggerEdge edge;
|
||||
float distance_x, distance_y;
|
||||
|
||||
@ -152,8 +155,7 @@ static guint gesture_signals[LAST_SIGNAL] = { 0, };
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterGestureAction, clutter_gesture_action, CLUTTER_TYPE_ACTION)
|
||||
|
||||
static GesturePoint *
|
||||
gesture_register_point (ClutterGestureAction *action,
|
||||
const ClutterEvent *event)
|
||||
gesture_register_point (ClutterGestureAction *action, ClutterEvent *event)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (action);
|
||||
@ -186,8 +188,8 @@ gesture_register_point (ClutterGestureAction *action,
|
||||
|
||||
static GesturePoint *
|
||||
gesture_find_point (ClutterGestureAction *action,
|
||||
const ClutterEvent *event,
|
||||
int *position)
|
||||
ClutterEvent *event,
|
||||
gint *position)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (action);
|
||||
@ -230,8 +232,8 @@ gesture_unregister_point (ClutterGestureAction *action, gint position)
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_update_motion_point (GesturePoint *point,
|
||||
const ClutterEvent *event)
|
||||
gesture_update_motion_point (GesturePoint *point,
|
||||
ClutterEvent *event)
|
||||
{
|
||||
gfloat motion_x, motion_y;
|
||||
gint64 _time;
|
||||
@ -252,8 +254,8 @@ gesture_update_motion_point (GesturePoint *point,
|
||||
}
|
||||
|
||||
static void
|
||||
gesture_update_release_point (GesturePoint *point,
|
||||
const ClutterEvent *event)
|
||||
gesture_update_release_point (GesturePoint *point,
|
||||
ClutterEvent *event)
|
||||
{
|
||||
gint64 _time;
|
||||
|
||||
@ -281,7 +283,7 @@ gesture_get_default_threshold (void)
|
||||
static gboolean
|
||||
gesture_point_pass_threshold (ClutterGestureAction *action,
|
||||
GesturePoint *point,
|
||||
const ClutterEvent *event)
|
||||
ClutterEvent *event)
|
||||
{
|
||||
float threshold_x, threshold_y;
|
||||
gfloat motion_x, motion_y;
|
||||
@ -310,6 +312,8 @@ cancel_gesture (ClutterGestureAction *action)
|
||||
|
||||
priv->in_gesture = FALSE;
|
||||
|
||||
g_clear_signal_handler (&priv->stage_capture_id, priv->stage);
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
||||
g_signal_emit (action, gesture_signals[GESTURE_CANCEL], 0, actor);
|
||||
|
||||
@ -350,50 +354,34 @@ begin_gesture (ClutterGestureAction *action,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_gesture_action_handle_event (ClutterAction *action,
|
||||
const ClutterEvent *event)
|
||||
stage_captured_event_cb (ClutterActor *stage,
|
||||
ClutterEvent *event,
|
||||
ClutterGestureAction *action)
|
||||
{
|
||||
ClutterGestureAction *gesture_action = CLUTTER_GESTURE_ACTION (action);
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (gesture_action);
|
||||
ClutterActor *actor =
|
||||
clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
||||
clutter_gesture_action_get_instance_private (action);
|
||||
ClutterActor *actor;
|
||||
gint position;
|
||||
float threshold_x, threshold_y;
|
||||
gboolean return_value;
|
||||
GesturePoint *point;
|
||||
ClutterEventType event_type;
|
||||
|
||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
|
||||
event_type = clutter_event_type (event);
|
||||
if (event_type != CLUTTER_TOUCH_CANCEL &&
|
||||
event_type != CLUTTER_TOUCH_UPDATE &&
|
||||
event_type != CLUTTER_TOUCH_END &&
|
||||
event_type != CLUTTER_MOTION &&
|
||||
event_type != CLUTTER_BUTTON_RELEASE)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
event_type = clutter_event_type (event);
|
||||
if ((point = gesture_find_point (action, event, &position)) == NULL)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if (event_type == CLUTTER_BUTTON_PRESS ||
|
||||
event_type == CLUTTER_TOUCH_BEGIN)
|
||||
{
|
||||
point = gesture_register_point (gesture_action, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((point = gesture_find_point (gesture_action, event, &position)) == NULL)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
||||
|
||||
switch (clutter_event_type (event))
|
||||
{
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
case CLUTTER_TOUCH_BEGIN:
|
||||
if (priv->stage == NULL)
|
||||
priv->stage = clutter_actor_get_stage (actor);
|
||||
|
||||
/* Start the gesture immediately if the gesture has no
|
||||
* _TRIGGER_EDGE_AFTER drag threshold. */
|
||||
if ((priv->points->len >= priv->requested_nb_points) &&
|
||||
(priv->edge != CLUTTER_GESTURE_TRIGGER_EDGE_AFTER))
|
||||
begin_gesture (gesture_action, actor);
|
||||
|
||||
break;
|
||||
case CLUTTER_MOTION:
|
||||
{
|
||||
ClutterModifierType mods = clutter_event_get_state (event);
|
||||
@ -404,7 +392,7 @@ clutter_gesture_action_handle_event (ClutterAction *action,
|
||||
*/
|
||||
if (!(mods & CLUTTER_BUTTON1_MASK))
|
||||
{
|
||||
cancel_gesture (gesture_action);
|
||||
cancel_gesture (action);
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
}
|
||||
@ -422,41 +410,41 @@ clutter_gesture_action_handle_event (ClutterAction *action,
|
||||
/* Wait until the drag threshold has been exceeded
|
||||
* before starting _TRIGGER_EDGE_AFTER gestures. */
|
||||
if (priv->edge == CLUTTER_GESTURE_TRIGGER_EDGE_AFTER &&
|
||||
gesture_point_pass_threshold (gesture_action, point, event))
|
||||
gesture_point_pass_threshold (action, point, event))
|
||||
{
|
||||
gesture_update_motion_point (point, event);
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
gesture_update_motion_point (point, event);
|
||||
if (!begin_gesture (action, actor))
|
||||
{
|
||||
if ((point = gesture_find_point (action, event, &position)) != NULL)
|
||||
gesture_update_motion_point (point, event);
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
if (!begin_gesture (gesture_action, actor))
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if ((point = gesture_find_point (gesture_action, event, &position)) == NULL)
|
||||
if ((point = gesture_find_point (action, event, &position)) == NULL)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
gesture_update_motion_point (point, event);
|
||||
|
||||
g_signal_emit (gesture_action, gesture_signals[GESTURE_PROGRESS], 0, actor,
|
||||
g_signal_emit (action, gesture_signals[GESTURE_PROGRESS], 0, actor,
|
||||
&return_value);
|
||||
if (!return_value)
|
||||
{
|
||||
cancel_gesture (gesture_action);
|
||||
cancel_gesture (action);
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
/* Check if a _TRIGGER_EDGE_BEFORE gesture needs to be cancelled because
|
||||
* the drag threshold has been exceeded. */
|
||||
clutter_gesture_action_get_threshold_trigger_distance (gesture_action,
|
||||
&threshold_x,
|
||||
&threshold_y);
|
||||
clutter_gesture_action_get_threshold_trigger_distance (action, &threshold_x, &threshold_y);
|
||||
if (priv->edge == CLUTTER_GESTURE_TRIGGER_EDGE_BEFORE &&
|
||||
((fabsf (point->press_y - point->last_motion_y) > threshold_y) ||
|
||||
(fabsf (point->press_x - point->last_motion_x) > threshold_x)))
|
||||
{
|
||||
cancel_gesture (gesture_action);
|
||||
cancel_gesture (action);
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
break;
|
||||
@ -470,10 +458,10 @@ clutter_gesture_action_handle_event (ClutterAction *action,
|
||||
((priv->points->len - 1) < priv->requested_nb_points))
|
||||
{
|
||||
priv->in_gesture = FALSE;
|
||||
g_signal_emit (gesture_action, gesture_signals[GESTURE_END], 0, actor);
|
||||
g_signal_emit (action, gesture_signals[GESTURE_END], 0, actor);
|
||||
}
|
||||
|
||||
gesture_unregister_point (gesture_action, position);
|
||||
gesture_unregister_point (action, position);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -484,10 +472,10 @@ clutter_gesture_action_handle_event (ClutterAction *action,
|
||||
if (priv->in_gesture)
|
||||
{
|
||||
priv->in_gesture = FALSE;
|
||||
cancel_gesture (gesture_action);
|
||||
cancel_gesture (action);
|
||||
}
|
||||
|
||||
gesture_unregister_point (gesture_action, position);
|
||||
gesture_unregister_point (action, position);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -495,9 +483,85 @@ clutter_gesture_action_handle_event (ClutterAction *action,
|
||||
break;
|
||||
}
|
||||
|
||||
return priv->in_gesture ?
|
||||
CLUTTER_EVENT_STOP :
|
||||
CLUTTER_EVENT_PROPAGATE;
|
||||
if (priv->points->len == 0)
|
||||
g_clear_signal_handler (&priv->stage_capture_id, priv->stage);
|
||||
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
actor_captured_event_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
ClutterGestureAction *action)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (action);
|
||||
GesturePoint *point G_GNUC_UNUSED;
|
||||
|
||||
if ((clutter_event_type (event) != CLUTTER_BUTTON_PRESS) &&
|
||||
(clutter_event_type (event) != CLUTTER_TOUCH_BEGIN))
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
point = gesture_register_point (action, event);
|
||||
|
||||
if (priv->stage == NULL)
|
||||
priv->stage = clutter_actor_get_stage (actor);
|
||||
|
||||
if (priv->stage_capture_id == 0)
|
||||
priv->stage_capture_id =
|
||||
g_signal_connect_after (priv->stage, "captured-event",
|
||||
G_CALLBACK (stage_captured_event_cb),
|
||||
action);
|
||||
|
||||
/* Start the gesture immediately if the gesture has no
|
||||
* _TRIGGER_EDGE_AFTER drag threshold. */
|
||||
if ((priv->points->len >= priv->requested_nb_points) &&
|
||||
(priv->edge != CLUTTER_GESTURE_TRIGGER_EDGE_AFTER))
|
||||
begin_gesture (action, actor);
|
||||
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_gesture_action_set_actor (ClutterActorMeta *meta,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (CLUTTER_GESTURE_ACTION (meta));
|
||||
ClutterActorMetaClass *meta_class =
|
||||
CLUTTER_ACTOR_META_CLASS (clutter_gesture_action_parent_class);
|
||||
|
||||
if (priv->actor_capture_id != 0)
|
||||
{
|
||||
ClutterActor *old_actor = clutter_actor_meta_get_actor (meta);
|
||||
|
||||
if (old_actor != NULL)
|
||||
g_clear_signal_handler (&priv->actor_capture_id, old_actor);
|
||||
|
||||
priv->actor_capture_id = 0;
|
||||
}
|
||||
|
||||
if (priv->stage_capture_id != 0)
|
||||
{
|
||||
if (priv->stage != NULL)
|
||||
g_clear_signal_handler (&priv->stage_capture_id, priv->stage);
|
||||
|
||||
priv->stage_capture_id = 0;
|
||||
priv->stage = NULL;
|
||||
}
|
||||
|
||||
if (actor != NULL)
|
||||
{
|
||||
priv->actor_capture_id =
|
||||
g_signal_connect (actor, "captured-event",
|
||||
G_CALLBACK (actor_captured_event_cb),
|
||||
meta);
|
||||
}
|
||||
|
||||
meta_class->set_actor (meta, actor);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -510,13 +574,8 @@ clutter_gesture_action_set_enabled (ClutterActorMeta *meta,
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (gesture_action);
|
||||
|
||||
if (!is_enabled)
|
||||
{
|
||||
if (priv->in_gesture)
|
||||
cancel_gesture (gesture_action);
|
||||
else
|
||||
g_array_set_size (priv->points, 0);
|
||||
}
|
||||
if (!is_enabled && priv->in_gesture)
|
||||
cancel_gesture (gesture_action);
|
||||
|
||||
meta_class->set_enabled (meta, is_enabled);
|
||||
}
|
||||
@ -621,16 +680,14 @@ clutter_gesture_action_class_init (ClutterGestureActionClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
|
||||
ClutterActionClass *action_class = CLUTTER_ACTION_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = clutter_gesture_action_finalize;
|
||||
gobject_class->set_property = clutter_gesture_action_set_property;
|
||||
gobject_class->get_property = clutter_gesture_action_get_property;
|
||||
|
||||
meta_class->set_actor = clutter_gesture_action_set_actor;
|
||||
meta_class->set_enabled = clutter_gesture_action_set_enabled;
|
||||
|
||||
action_class->handle_event = clutter_gesture_action_handle_event;
|
||||
|
||||
klass->gesture_begin = default_event_handler;
|
||||
klass->gesture_progress = default_event_handler;
|
||||
klass->gesture_prepare = default_event_handler;
|
||||
|
@ -29,23 +29,6 @@
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-types.h"
|
||||
|
||||
static gboolean
|
||||
graphene_matrix_progress (const GValue *a,
|
||||
const GValue *b,
|
||||
double progress,
|
||||
GValue *retval)
|
||||
{
|
||||
const graphene_matrix_t *am = g_value_get_boxed (a);
|
||||
const graphene_matrix_t *bm = g_value_get_boxed (b);
|
||||
graphene_matrix_t res;
|
||||
|
||||
graphene_matrix_interpolate (am, bm, progress, &res);
|
||||
|
||||
g_value_set_boxed (retval, &res);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
graphene_point_progress (const GValue *a,
|
||||
const GValue *b,
|
||||
@ -117,8 +100,6 @@ graphene_size_progress (const GValue *a,
|
||||
void
|
||||
clutter_graphene_init (void)
|
||||
{
|
||||
clutter_interval_register_progress_func (GRAPHENE_TYPE_MATRIX,
|
||||
graphene_matrix_progress);
|
||||
clutter_interval_register_progress_func (GRAPHENE_TYPE_POINT,
|
||||
graphene_point_progress);
|
||||
clutter_interval_register_progress_func (GRAPHENE_TYPE_POINT3D,
|
||||
|
96
clutter/clutter/clutter-group.h
Normal file
96
clutter/clutter/clutter-group.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2006 OpenedHand
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_GROUP_H__
|
||||
#define __CLUTTER_GROUP_H__
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <clutter/clutter-types.h>
|
||||
#include <clutter/clutter-actor.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_GROUP (clutter_group_get_type ())
|
||||
#define CLUTTER_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_GROUP, ClutterGroup))
|
||||
#define CLUTTER_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_GROUP, ClutterGroupClass))
|
||||
#define CLUTTER_IS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_GROUP))
|
||||
#define CLUTTER_IS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_GROUP))
|
||||
#define CLUTTER_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_GROUP, ClutterGroupClass))
|
||||
|
||||
/* XXX - ClutterGroup is to be considered fully deprecated; the only
|
||||
* reason we keep this header is because ClutterStage inherits from
|
||||
* ClutterGroup, and thus we need to have a structure definition for
|
||||
* the Stage object to expand.
|
||||
*/
|
||||
|
||||
typedef struct _ClutterGroup ClutterGroup;
|
||||
typedef struct _ClutterGroupClass ClutterGroupClass;
|
||||
typedef struct _ClutterGroupPrivate ClutterGroupPrivate;
|
||||
|
||||
/**
|
||||
* ClutterGroup:
|
||||
*
|
||||
* The #ClutterGroup structure contains only private data
|
||||
* and should be accessed using the provided API
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
struct _ClutterGroup
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterActor parent_instance;
|
||||
|
||||
ClutterGroupPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterGroupClass:
|
||||
*
|
||||
* The #ClutterGroupClass structure contains only private data
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
struct _ClutterGroupClass
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
void (*_clutter_reserved1) (void);
|
||||
void (*_clutter_reserved2) (void);
|
||||
void (*_clutter_reserved3) (void);
|
||||
void (*_clutter_reserved4) (void);
|
||||
void (*_clutter_reserved5) (void);
|
||||
void (*_clutter_reserved6) (void);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_group_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_GROUP_H__ */
|
@ -44,7 +44,7 @@ _clutter_id_pool_new (guint initial_size)
|
||||
{
|
||||
ClutterIDPool *self;
|
||||
|
||||
self = g_new0 (ClutterIDPool, 1);
|
||||
self = g_slice_new (ClutterIDPool);
|
||||
|
||||
self->array = g_array_sized_new (FALSE, FALSE,
|
||||
sizeof (gpointer), initial_size);
|
||||
@ -59,7 +59,7 @@ _clutter_id_pool_free (ClutterIDPool *id_pool)
|
||||
|
||||
g_array_free (id_pool->array, TRUE);
|
||||
g_slist_free (id_pool->free_ids);
|
||||
g_free (id_pool);
|
||||
g_slice_free (ClutterIDPool, id_pool);
|
||||
}
|
||||
|
||||
guint32
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||
|
||||
#include "clutter-image.h"
|
||||
|
||||
#include "clutter-actor-private.h"
|
||||
|
@ -32,6 +32,44 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _ClutterAxisInfo
|
||||
{
|
||||
ClutterInputAxis axis;
|
||||
|
||||
double min_axis;
|
||||
double max_axis;
|
||||
|
||||
double min_value;
|
||||
double max_value;
|
||||
|
||||
double resolution;
|
||||
} ClutterAxisInfo;
|
||||
|
||||
typedef struct _ClutterKeyInfo
|
||||
{
|
||||
guint keyval;
|
||||
ClutterModifierType modifiers;
|
||||
} ClutterKeyInfo;
|
||||
|
||||
typedef struct _ClutterScrollInfo
|
||||
{
|
||||
guint axis_id;
|
||||
ClutterScrollDirection direction;
|
||||
double increment;
|
||||
|
||||
double last_value;
|
||||
guint last_value_valid : 1;
|
||||
} ClutterScrollInfo;
|
||||
|
||||
typedef struct _ClutterTouchInfo
|
||||
{
|
||||
ClutterEventSequence *sequence;
|
||||
ClutterActor *actor;
|
||||
|
||||
float current_x;
|
||||
float current_y;
|
||||
} ClutterTouchInfo;
|
||||
|
||||
typedef struct _ClutterPtrA11yData
|
||||
{
|
||||
int n_btn_pressed;
|
||||
@ -53,15 +91,165 @@ struct _ClutterInputDevice
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
int id;
|
||||
|
||||
ClutterInputDeviceType device_type;
|
||||
ClutterInputMode device_mode;
|
||||
|
||||
char *device_name;
|
||||
|
||||
ClutterSeat *seat;
|
||||
|
||||
ClutterBackend *backend;
|
||||
|
||||
/* the associated device */
|
||||
ClutterInputDevice *associated;
|
||||
|
||||
GList *slaves;
|
||||
|
||||
/* the actor underneath the pointer */
|
||||
ClutterActor *cursor_actor;
|
||||
GHashTable *inv_touch_sequence_actors;
|
||||
|
||||
/* the actor that has a grab in place for the device */
|
||||
ClutterActor *pointer_grab_actor;
|
||||
ClutterActor *keyboard_grab_actor;
|
||||
GHashTable *sequence_grab_actors;
|
||||
GHashTable *inv_sequence_grab_actors;
|
||||
|
||||
/* the current click count */
|
||||
int click_count;
|
||||
|
||||
/* the stage the device is on */
|
||||
ClutterStage *stage;
|
||||
|
||||
/* the current state */
|
||||
float current_x;
|
||||
float current_y;
|
||||
uint32_t current_time;
|
||||
int current_button_number;
|
||||
ClutterModifierType current_state;
|
||||
|
||||
/* the current touch points states */
|
||||
GHashTable *touch_sequences_info;
|
||||
|
||||
/* the previous state, used for click count generation */
|
||||
int previous_x;
|
||||
int previous_y;
|
||||
uint32_t previous_time;
|
||||
int previous_button_number;
|
||||
ClutterModifierType previous_state;
|
||||
|
||||
GArray *axes;
|
||||
|
||||
guint n_keys;
|
||||
GArray *keys;
|
||||
|
||||
GArray *scroll_info;
|
||||
|
||||
char *vendor_id;
|
||||
char *product_id;
|
||||
char *node_path;
|
||||
|
||||
GPtrArray *tools;
|
||||
|
||||
int n_rings;
|
||||
int n_strips;
|
||||
int n_mode_groups;
|
||||
|
||||
ClutterInputDeviceMapping mapping_mode;
|
||||
|
||||
guint has_cursor : 1;
|
||||
guint is_enabled : 1;
|
||||
|
||||
/* Accessiblity */
|
||||
ClutterVirtualInputDevice *accessibility_virtual_device;
|
||||
ClutterPtrA11yData *ptr_a11y_data;
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_set_associated_device (ClutterInputDevice *device,
|
||||
ClutterInputDevice *associated);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_add_slave (ClutterInputDevice *master,
|
||||
ClutterInputDevice *slave);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_remove_slave (ClutterInputDevice *master,
|
||||
ClutterInputDevice *slave);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_input_device_update_from_tool (ClutterInputDevice *device,
|
||||
ClutterInputDeviceTool *tool);
|
||||
CLUTTER_EXPORT
|
||||
ClutterStage * _clutter_input_device_get_stage (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_set_stage (ClutterInputDevice *device,
|
||||
ClutterStage *stage);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_set_coords (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence,
|
||||
gfloat x,
|
||||
gfloat y,
|
||||
ClutterStage *stage);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_set_state (ClutterInputDevice *device,
|
||||
ClutterModifierType state);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_set_time (ClutterInputDevice *device,
|
||||
guint32 time_);
|
||||
void _clutter_input_device_set_actor (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence,
|
||||
ClutterActor *actor,
|
||||
gboolean emit_crossing);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_input_device_update (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence,
|
||||
gboolean emit_crossing);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_add_event_sequence (ClutterInputDevice *device,
|
||||
ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device,
|
||||
ClutterEvent *event);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_set_n_keys (ClutterInputDevice *device,
|
||||
guint n_keys);
|
||||
CLUTTER_EXPORT
|
||||
gboolean _clutter_input_device_translate_axis (ClutterInputDevice *device,
|
||||
guint index_,
|
||||
gdouble value,
|
||||
gdouble *axis_value);
|
||||
CLUTTER_EXPORT
|
||||
guint _clutter_input_device_add_axis (ClutterInputDevice *device,
|
||||
ClutterInputAxis axis,
|
||||
gdouble minimum,
|
||||
gdouble maximum,
|
||||
gdouble resolution);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_reset_axes (ClutterInputDevice *device);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_add_scroll_info (ClutterInputDevice *device,
|
||||
guint index_,
|
||||
ClutterScrollDirection direction,
|
||||
gdouble increment);
|
||||
CLUTTER_EXPORT
|
||||
gboolean _clutter_input_device_get_scroll_delta (ClutterInputDevice *device,
|
||||
guint index_,
|
||||
gdouble value,
|
||||
ClutterScrollDirection *direction_p,
|
||||
gdouble *delta_p);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_reset_scroll_info (ClutterInputDevice *device);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_input_device_add_tool (ClutterInputDevice *device,
|
||||
ClutterInputDeviceTool *tool);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterInputDeviceTool *
|
||||
clutter_input_device_lookup_tool (ClutterInputDevice *device,
|
||||
guint64 serial,
|
||||
ClutterInputDeviceToolType type);
|
||||
|
||||
#endif /* CLUTTER_INPUT_DEVICE_PRIVATE_H */
|
||||
|
@ -33,7 +33,6 @@ struct _ClutterInputDeviceToolPrivate
|
||||
ClutterInputDeviceToolType type;
|
||||
guint64 serial;
|
||||
guint64 id;
|
||||
ClutterInputAxisFlags axes;
|
||||
};
|
||||
|
||||
enum
|
||||
@ -42,7 +41,6 @@ enum
|
||||
PROP_TYPE,
|
||||
PROP_SERIAL,
|
||||
PROP_ID,
|
||||
PROP_AXES,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
@ -72,9 +70,6 @@ clutter_input_device_tool_set_property (GObject *object,
|
||||
case PROP_ID:
|
||||
priv->id = g_value_get_uint64 (value);
|
||||
break;
|
||||
case PROP_AXES:
|
||||
priv->axes = g_value_get_flags (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@ -102,9 +97,6 @@ clutter_input_device_tool_get_property (GObject *object,
|
||||
case PROP_ID:
|
||||
g_value_set_uint64 (value, priv->id);
|
||||
break;
|
||||
case PROP_AXES:
|
||||
g_value_set_flags (value, priv->axes);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@ -137,13 +129,6 @@ clutter_input_device_tool_class_init (ClutterInputDeviceToolClass *klass)
|
||||
P_("Tool ID"),
|
||||
0, G_MAXUINT64, 0,
|
||||
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
props[PROP_AXES] =
|
||||
g_param_spec_flags ("axes",
|
||||
P_("Axes"),
|
||||
P_("Axes"),
|
||||
CLUTTER_TYPE_INPUT_AXIS_FLAGS,
|
||||
CLUTTER_INPUT_AXIS_FLAG_NONE,
|
||||
CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, props);
|
||||
}
|
||||
@ -219,15 +204,3 @@ clutter_input_device_tool_get_id (ClutterInputDeviceTool *tool)
|
||||
|
||||
return priv->id;
|
||||
}
|
||||
|
||||
ClutterInputAxisFlags
|
||||
clutter_input_device_tool_get_axes (ClutterInputDeviceTool *tool)
|
||||
{
|
||||
ClutterInputDeviceToolPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL (tool), 0);
|
||||
|
||||
priv = clutter_input_device_tool_get_instance_private (tool);
|
||||
|
||||
return priv->axes;
|
||||
}
|
||||
|
@ -64,9 +64,6 @@ ClutterInputDeviceToolType clutter_input_device_tool_get_tool_type (ClutterInput
|
||||
CLUTTER_EXPORT
|
||||
guint64 clutter_input_device_tool_get_id (ClutterInputDeviceTool *tool);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterInputAxisFlags clutter_input_device_tool_get_axes (ClutterInputDeviceTool *tool);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_INPUT_DEVICE_TOOL_H__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -34,10 +34,19 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef void (*ClutterEmitInputDeviceEvent) (ClutterEvent *event,
|
||||
ClutterInputDevice *device);
|
||||
|
||||
struct _ClutterInputDeviceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
gboolean (* keycode_to_evdev) (ClutterInputDevice *device,
|
||||
guint hardware_keycode,
|
||||
guint *evdev_keycode);
|
||||
void (* update_from_tool) (ClutterInputDevice *device,
|
||||
ClutterInputDeviceTool *tool);
|
||||
|
||||
gboolean (* is_mode_switch_button) (ClutterInputDevice *device,
|
||||
guint group,
|
||||
guint button);
|
||||
@ -47,9 +56,10 @@ struct _ClutterInputDeviceClass
|
||||
gboolean (* is_grouped) (ClutterInputDevice *device,
|
||||
ClutterInputDevice *other_device);
|
||||
|
||||
int (* get_pad_feature_group) (ClutterInputDevice *device,
|
||||
ClutterInputDevicePadFeature feature,
|
||||
int n_feature);
|
||||
/* Keyboard accessbility */
|
||||
void (* process_kbd_a11y_event) (ClutterEvent *event,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEmitInputDeviceEvent emit_event_func);
|
||||
};
|
||||
|
||||
#define CLUTTER_TYPE_INPUT_DEVICE (clutter_input_device_get_type ())
|
||||
@ -72,13 +82,64 @@ GType clutter_input_device_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterInputDeviceType clutter_input_device_get_device_type (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
gint clutter_input_device_get_device_id (ClutterInputDevice *device);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_input_device_get_coords (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence,
|
||||
graphene_point_t *point);
|
||||
CLUTTER_EXPORT
|
||||
ClutterModifierType clutter_input_device_get_modifier_state (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_input_device_get_pointer_actor (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
ClutterStage * clutter_input_device_get_pointer_stage (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
const gchar * clutter_input_device_get_device_name (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
ClutterInputMode clutter_input_device_get_device_mode (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_input_device_get_has_cursor (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_input_device_set_enabled (ClutterInputDevice *device,
|
||||
gboolean enabled);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_input_device_get_enabled (ClutterInputDevice *device);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
guint clutter_input_device_get_n_axes (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
ClutterInputAxis clutter_input_device_get_axis (ClutterInputDevice *device,
|
||||
guint index_);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_input_device_get_axis_value (ClutterInputDevice *device,
|
||||
gdouble *axes,
|
||||
ClutterInputAxis axis,
|
||||
gdouble *value);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
guint clutter_input_device_get_n_keys (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_input_device_set_key (ClutterInputDevice *device,
|
||||
guint index_,
|
||||
guint keyval,
|
||||
ClutterModifierType modifiers);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_input_device_get_key (ClutterInputDevice *device,
|
||||
guint index_,
|
||||
guint *keyval,
|
||||
ClutterModifierType *modifiers);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterInputDevice * clutter_input_device_get_associated_device (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
GList * clutter_input_device_get_slave_devices (ClutterInputDevice *device);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_input_device_update_from_event (ClutterInputDevice *device,
|
||||
ClutterEvent *event,
|
||||
gboolean update_stage);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_input_device_grab (ClutterInputDevice *device,
|
||||
@ -99,6 +160,11 @@ CLUTTER_EXPORT
|
||||
ClutterActor * clutter_input_device_sequence_get_grabbed_actor (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_input_device_keycode_to_evdev (ClutterInputDevice *device,
|
||||
guint hardware_keycode,
|
||||
guint *evdev_keycode);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
const gchar * clutter_input_device_get_vendor_id (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
@ -110,9 +176,6 @@ CLUTTER_EXPORT
|
||||
gint clutter_input_device_get_n_strips (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
gint clutter_input_device_get_n_mode_groups (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
int clutter_input_device_get_n_buttons (ClutterInputDevice *device);
|
||||
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gint clutter_input_device_get_group_n_modes (ClutterInputDevice *device,
|
||||
@ -129,17 +192,18 @@ gint clutter_input_device_get_mode_switch_button_group (Clutt
|
||||
CLUTTER_EXPORT
|
||||
const gchar * clutter_input_device_get_device_node (ClutterInputDevice *device);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterInputDeviceMapping clutter_input_device_get_mapping_mode (ClutterInputDevice *device);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_input_device_set_mapping_mode (ClutterInputDevice *device,
|
||||
ClutterInputDeviceMapping mapping);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_input_device_is_grouped (ClutterInputDevice *device,
|
||||
ClutterInputDevice *other_device);
|
||||
CLUTTER_EXPORT
|
||||
ClutterSeat * clutter_input_device_get_seat (ClutterInputDevice *device);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
int clutter_input_device_get_pad_feature_group (ClutterInputDevice *device,
|
||||
ClutterInputDevicePadFeature feature,
|
||||
int n_feature);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_INPUT_DEVICE_H__ */
|
||||
|
@ -30,8 +30,6 @@ typedef struct _ClutterInputFocusPrivate ClutterInputFocusPrivate;
|
||||
struct _ClutterInputFocusPrivate
|
||||
{
|
||||
ClutterInputMethod *im;
|
||||
char *preedit;
|
||||
ClutterPreeditResetMode mode;
|
||||
};
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterInputFocus, clutter_input_focus, G_TYPE_OBJECT)
|
||||
@ -55,25 +53,9 @@ clutter_input_focus_real_focus_out (ClutterInputFocus *focus)
|
||||
priv->im = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_focus_finalize (GObject *object)
|
||||
{
|
||||
ClutterInputFocus *focus = CLUTTER_INPUT_FOCUS (object);
|
||||
ClutterInputFocusPrivate *priv =
|
||||
clutter_input_focus_get_instance_private (focus);
|
||||
|
||||
g_clear_pointer (&priv->preedit, g_free);
|
||||
|
||||
G_OBJECT_CLASS (clutter_input_focus_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_focus_class_init (ClutterInputFocusClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = clutter_input_focus_finalize;
|
||||
|
||||
klass->focus_in = clutter_input_focus_real_focus_in;
|
||||
klass->focus_out = clutter_input_focus_real_focus_out;
|
||||
}
|
||||
@ -103,16 +85,6 @@ clutter_input_focus_reset (ClutterInputFocus *focus)
|
||||
|
||||
priv = clutter_input_focus_get_instance_private (focus);
|
||||
|
||||
if (priv->preedit)
|
||||
{
|
||||
if (priv->mode == CLUTTER_PREEDIT_RESET_COMMIT)
|
||||
clutter_input_focus_commit (focus, priv->preedit);
|
||||
|
||||
clutter_input_focus_set_preedit_text (focus, NULL, 0);
|
||||
g_clear_pointer (&priv->preedit, g_free);
|
||||
}
|
||||
|
||||
priv->mode = CLUTTER_PREEDIT_RESET_CLEAR;
|
||||
clutter_input_method_reset (priv->im);
|
||||
}
|
||||
|
||||
@ -175,8 +147,8 @@ clutter_input_focus_set_content_purpose (ClutterInputFocus *focus,
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_input_focus_filter_event (ClutterInputFocus *focus,
|
||||
const ClutterEvent *event)
|
||||
clutter_input_focus_filter_key_event (ClutterInputFocus *focus,
|
||||
const ClutterKeyEvent *key)
|
||||
{
|
||||
ClutterInputFocusPrivate *priv;
|
||||
|
||||
@ -185,41 +157,7 @@ clutter_input_focus_filter_event (ClutterInputFocus *focus,
|
||||
|
||||
priv = clutter_input_focus_get_instance_private (focus);
|
||||
|
||||
if (event->type == CLUTTER_KEY_PRESS ||
|
||||
event->type == CLUTTER_KEY_RELEASE)
|
||||
{
|
||||
return clutter_input_method_filter_key_event (priv->im, &event->key);
|
||||
}
|
||||
else if (event->type == CLUTTER_IM_COMMIT)
|
||||
{
|
||||
clutter_input_focus_commit (focus, event->im.text);
|
||||
return TRUE;
|
||||
}
|
||||
else if (event->type == CLUTTER_IM_DELETE)
|
||||
{
|
||||
clutter_input_focus_delete_surrounding (focus, event->im.offset,
|
||||
event->im.len);
|
||||
return TRUE;
|
||||
}
|
||||
else if (event->type == CLUTTER_IM_PREEDIT)
|
||||
{
|
||||
g_clear_pointer (&priv->preedit, g_free);
|
||||
priv->preedit = g_strdup (event->im.text);
|
||||
priv->mode = event->im.mode;
|
||||
clutter_input_focus_set_preedit_text (focus, event->im.text,
|
||||
event->im.offset);
|
||||
return TRUE;
|
||||
}
|
||||
else if (event->type == CLUTTER_TOUCH_BEGIN ||
|
||||
(event->type == CLUTTER_BUTTON_PRESS &&
|
||||
event->button.button == CLUTTER_BUTTON_PRIMARY))
|
||||
{
|
||||
clutter_input_focus_reset (focus);
|
||||
/* pointing events are not consumed by IMs */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return clutter_input_method_filter_key_event (priv->im, key);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -72,8 +72,8 @@ CLUTTER_EXPORT
|
||||
void clutter_input_focus_set_content_purpose (ClutterInputFocus *focus,
|
||||
ClutterInputContentPurpose purpose);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_input_focus_filter_event (ClutterInputFocus *focus,
|
||||
const ClutterEvent *event);
|
||||
gboolean clutter_input_focus_filter_key_event (ClutterInputFocus *focus,
|
||||
const ClutterKeyEvent *key);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_input_focus_set_can_show_preedit (ClutterInputFocus *focus,
|
||||
gboolean can_show_preedit);
|
||||
|
@ -277,48 +277,17 @@ clutter_input_method_get_focus (ClutterInputMethod *im)
|
||||
return priv->focus;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_method_put_im_event (ClutterInputMethod *im,
|
||||
ClutterEventType event_type,
|
||||
const char *text,
|
||||
int32_t offset,
|
||||
uint32_t len,
|
||||
ClutterPreeditResetMode mode)
|
||||
{
|
||||
ClutterInputDevice *keyboard;
|
||||
ClutterSeat *seat;
|
||||
ClutterStageManager *stage_manager;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event;
|
||||
|
||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||
keyboard = clutter_seat_get_keyboard (seat);
|
||||
stage_manager = clutter_stage_manager_get_default ();
|
||||
stage = clutter_stage_manager_get_default_stage (stage_manager);
|
||||
|
||||
event = clutter_event_new (event_type);
|
||||
event->im.text = g_strdup (text);
|
||||
event->im.offset = offset;
|
||||
event->im.len = len;
|
||||
event->im.mode = mode;
|
||||
clutter_event_set_device (event, keyboard);
|
||||
clutter_event_set_source_device (event, keyboard);
|
||||
clutter_event_set_flags (event, CLUTTER_EVENT_FLAG_INPUT_METHOD);
|
||||
|
||||
clutter_event_set_stage (event, stage);
|
||||
|
||||
clutter_event_put (event);
|
||||
clutter_event_free (event);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_commit (ClutterInputMethod *im,
|
||||
const gchar *text)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im));
|
||||
|
||||
clutter_input_method_put_im_event (im, CLUTTER_IM_COMMIT, text, 0, 0,
|
||||
CLUTTER_PREEDIT_RESET_CLEAR);
|
||||
priv = clutter_input_method_get_instance_private (im);
|
||||
if (priv->focus)
|
||||
clutter_input_focus_commit (priv->focus, text);
|
||||
}
|
||||
|
||||
void
|
||||
@ -326,10 +295,13 @@ clutter_input_method_delete_surrounding (ClutterInputMethod *im,
|
||||
int offset,
|
||||
guint len)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im));
|
||||
|
||||
clutter_input_method_put_im_event (im, CLUTTER_IM_DELETE, NULL, offset, len,
|
||||
CLUTTER_PREEDIT_RESET_CLEAR);
|
||||
priv = clutter_input_method_get_instance_private (im);
|
||||
if (priv->focus)
|
||||
clutter_input_focus_delete_surrounding (priv->focus, offset, len);
|
||||
}
|
||||
|
||||
void
|
||||
@ -353,15 +325,17 @@ clutter_input_method_request_surrounding (ClutterInputMethod *im)
|
||||
* Sets the preedit text on the current input focus.
|
||||
**/
|
||||
void
|
||||
clutter_input_method_set_preedit_text (ClutterInputMethod *im,
|
||||
const gchar *preedit,
|
||||
unsigned int cursor,
|
||||
ClutterPreeditResetMode mode)
|
||||
clutter_input_method_set_preedit_text (ClutterInputMethod *im,
|
||||
const gchar *preedit,
|
||||
guint cursor)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im));
|
||||
|
||||
clutter_input_method_put_im_event (im, CLUTTER_IM_PREEDIT, preedit,
|
||||
cursor, 0, mode);
|
||||
priv = clutter_input_method_get_instance_private (im);
|
||||
if (priv->focus)
|
||||
clutter_input_focus_set_preedit_text (priv->focus, preedit, cursor);
|
||||
}
|
||||
|
||||
void
|
||||
@ -480,7 +454,6 @@ clutter_input_method_forward_key (ClutterInputMethod *im,
|
||||
ClutterInputMethodPrivate *priv;
|
||||
ClutterInputDevice *keyboard;
|
||||
ClutterSeat *seat;
|
||||
ClutterStageManager *stage_manager;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event;
|
||||
|
||||
@ -491,9 +464,10 @@ clutter_input_method_forward_key (ClutterInputMethod *im,
|
||||
return;
|
||||
|
||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||
stage_manager = clutter_stage_manager_get_default ();
|
||||
stage = clutter_stage_manager_get_default_stage (stage_manager);
|
||||
keyboard = clutter_seat_get_keyboard (seat);
|
||||
stage = _clutter_input_device_get_stage (keyboard);
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
event = clutter_event_new (press ? CLUTTER_KEY_PRESS : CLUTTER_KEY_RELEASE);
|
||||
event->key.time = time_;
|
||||
@ -501,7 +475,6 @@ clutter_input_method_forward_key (ClutterInputMethod *im,
|
||||
event->key.modifier_state = state;
|
||||
event->key.keyval = keyval;
|
||||
event->key.hardware_keycode = keycode;
|
||||
event->key.evdev_code = keycode - 8;
|
||||
event->key.unicode_value = clutter_keysym_to_unicode (keyval);
|
||||
|
||||
clutter_event_set_device (event, keyboard);
|
||||
|
@ -74,10 +74,9 @@ CLUTTER_EXPORT
|
||||
void clutter_input_method_request_surrounding (ClutterInputMethod *im);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_input_method_set_preedit_text (ClutterInputMethod *im,
|
||||
const gchar *preedit,
|
||||
unsigned int cursor,
|
||||
ClutterPreeditResetMode mode);
|
||||
void clutter_input_method_set_preedit_text (ClutterInputMethod *im,
|
||||
const gchar *preedit,
|
||||
guint cursor);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_input_method_notify_key_event (ClutterInputMethod *im,
|
||||
|
@ -36,9 +36,8 @@ static gboolean
|
||||
is_secondary_click_enabled (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
clutter_seat_get_pointer_a11y_settings (seat, &settings);
|
||||
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
|
||||
|
||||
return (settings.controls & CLUTTER_A11Y_SECONDARY_CLICK_ENABLED);
|
||||
}
|
||||
@ -47,9 +46,8 @@ static gboolean
|
||||
is_dwell_click_enabled (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
clutter_seat_get_pointer_a11y_settings (seat, &settings);
|
||||
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
|
||||
|
||||
return (settings.controls & CLUTTER_A11Y_DWELL_ENABLED);
|
||||
}
|
||||
@ -58,9 +56,8 @@ static unsigned int
|
||||
get_secondary_click_delay (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
clutter_seat_get_pointer_a11y_settings (seat, &settings);
|
||||
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
|
||||
|
||||
return settings.secondary_click_delay;
|
||||
}
|
||||
@ -69,9 +66,8 @@ static unsigned int
|
||||
get_dwell_delay (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
clutter_seat_get_pointer_a11y_settings (seat, &settings);
|
||||
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
|
||||
|
||||
return settings.dwell_delay;
|
||||
}
|
||||
@ -80,9 +76,8 @@ static unsigned int
|
||||
get_dwell_threshold (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
clutter_seat_get_pointer_a11y_settings (seat, &settings);
|
||||
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
|
||||
|
||||
return settings.dwell_threshold;
|
||||
}
|
||||
@ -91,9 +86,8 @@ static ClutterPointerA11yDwellMode
|
||||
get_dwell_mode (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
clutter_seat_get_pointer_a11y_settings (seat, &settings);
|
||||
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
|
||||
|
||||
return settings.dwell_mode;
|
||||
}
|
||||
@ -102,9 +96,8 @@ static ClutterPointerA11yDwellClickType
|
||||
get_dwell_click_type (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
clutter_seat_get_pointer_a11y_settings (seat, &settings);
|
||||
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
|
||||
|
||||
return settings.dwell_click_type;
|
||||
}
|
||||
@ -114,9 +107,8 @@ get_dwell_click_type_for_direction (ClutterInputDevice *device,
|
||||
ClutterPointerA11yDwellDirection direction)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
clutter_seat_get_pointer_a11y_settings (seat, &settings);
|
||||
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
|
||||
|
||||
if (direction == settings.dwell_gesture_single)
|
||||
return CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY;
|
||||
@ -171,12 +163,11 @@ static gboolean
|
||||
trigger_secondary_click (gpointer data)
|
||||
{
|
||||
ClutterInputDevice *device = data;
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
device->ptr_a11y_data->secondary_click_triggered = TRUE;
|
||||
device->ptr_a11y_data->secondary_click_timer = 0;
|
||||
|
||||
g_signal_emit_by_name (seat,
|
||||
g_signal_emit_by_name (device->seat,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
|
||||
@ -189,12 +180,11 @@ static void
|
||||
start_secondary_click_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
unsigned int delay = get_secondary_click_delay (device);
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
device->ptr_a11y_data->secondary_click_timer =
|
||||
clutter_threads_add_timeout (delay, trigger_secondary_click, device);
|
||||
|
||||
g_signal_emit_by_name (seat,
|
||||
g_signal_emit_by_name (device->seat,
|
||||
"ptr-a11y-timeout-started",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
|
||||
@ -204,14 +194,12 @@ start_secondary_click_timeout (ClutterInputDevice *device)
|
||||
static void
|
||||
stop_secondary_click_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
if (device->ptr_a11y_data->secondary_click_timer)
|
||||
{
|
||||
g_clear_handle_id (&device->ptr_a11y_data->secondary_click_timer,
|
||||
g_source_remove);
|
||||
|
||||
g_signal_emit_by_name (seat,
|
||||
g_signal_emit_by_name (device->seat,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
|
||||
@ -314,9 +302,8 @@ update_dwell_click_type (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
ClutterPointerA11yDwellClickType dwell_click_type;
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
clutter_seat_get_pointer_a11y_settings (seat, &settings);
|
||||
clutter_seat_get_pointer_a11y_settings (device->seat, &settings);
|
||||
|
||||
dwell_click_type = settings.dwell_click_type;
|
||||
switch (dwell_click_type)
|
||||
@ -341,9 +328,9 @@ update_dwell_click_type (ClutterInputDevice *device)
|
||||
if (dwell_click_type != settings.dwell_click_type)
|
||||
{
|
||||
settings.dwell_click_type = dwell_click_type;
|
||||
clutter_seat_set_pointer_a11y_settings (seat, &settings);
|
||||
clutter_seat_set_pointer_a11y_settings (device->seat, &settings);
|
||||
|
||||
g_signal_emit_by_name (seat,
|
||||
g_signal_emit_by_name (device->seat,
|
||||
"ptr-a11y-dwell-click-type-changed",
|
||||
dwell_click_type);
|
||||
}
|
||||
@ -437,7 +424,6 @@ trigger_dwell_gesture (gpointer data)
|
||||
ClutterInputDevice *device = data;
|
||||
ClutterPointerA11yDwellDirection direction;
|
||||
unsigned int delay = get_dwell_delay (device);
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
restore_dwell_position (device);
|
||||
direction = get_dwell_direction (device);
|
||||
@ -449,7 +435,7 @@ trigger_dwell_gesture (gpointer data)
|
||||
device->ptr_a11y_data->dwell_timer =
|
||||
clutter_threads_add_timeout (delay, trigger_clear_dwell_gesture, device);
|
||||
|
||||
g_signal_emit_by_name (seat,
|
||||
g_signal_emit_by_name (device->seat,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE,
|
||||
@ -462,13 +448,12 @@ static void
|
||||
start_dwell_gesture_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
unsigned int delay = get_dwell_delay (device);
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
device->ptr_a11y_data->dwell_timer =
|
||||
clutter_threads_add_timeout (delay, trigger_dwell_gesture, device);
|
||||
device->ptr_a11y_data->dwell_gesture_started = TRUE;
|
||||
|
||||
g_signal_emit_by_name (seat,
|
||||
g_signal_emit_by_name (device->seat,
|
||||
"ptr-a11y-timeout-started",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE,
|
||||
@ -479,11 +464,10 @@ static gboolean
|
||||
trigger_dwell_click (gpointer data)
|
||||
{
|
||||
ClutterInputDevice *device = data;
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
device->ptr_a11y_data->dwell_timer = 0;
|
||||
|
||||
g_signal_emit_by_name (seat,
|
||||
g_signal_emit_by_name (device->seat,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
|
||||
@ -509,12 +493,11 @@ static void
|
||||
start_dwell_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
unsigned int delay = get_dwell_delay (device);
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
device->ptr_a11y_data->dwell_timer =
|
||||
clutter_threads_add_timeout (delay, trigger_dwell_click, device);
|
||||
|
||||
g_signal_emit_by_name (seat,
|
||||
g_signal_emit_by_name (device->seat,
|
||||
"ptr-a11y-timeout-started",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
|
||||
@ -524,14 +507,12 @@ start_dwell_timeout (ClutterInputDevice *device)
|
||||
static void
|
||||
stop_dwell_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
if (device->ptr_a11y_data->dwell_timer)
|
||||
{
|
||||
g_clear_handle_id (&device->ptr_a11y_data->dwell_timer, g_source_remove);
|
||||
device->ptr_a11y_data->dwell_gesture_started = FALSE;
|
||||
|
||||
g_signal_emit_by_name (seat,
|
||||
g_signal_emit_by_name (device->seat,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
|
||||
@ -589,9 +570,8 @@ static gboolean
|
||||
is_device_core_pointer (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterInputDevice *core_pointer;
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
core_pointer = clutter_seat_get_pointer (seat);
|
||||
core_pointer = clutter_seat_get_pointer (device->seat);
|
||||
if (core_pointer == NULL)
|
||||
return FALSE;
|
||||
|
||||
@ -601,13 +581,11 @@ is_device_core_pointer (ClutterInputDevice *device)
|
||||
void
|
||||
_clutter_input_pointer_a11y_add_device (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterSeat *seat = clutter_input_device_get_seat (device);
|
||||
|
||||
if (!is_device_core_pointer (device))
|
||||
return;
|
||||
|
||||
device->accessibility_virtual_device =
|
||||
clutter_seat_create_virtual_device (seat,
|
||||
clutter_seat_create_virtual_device (device->seat,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
|
||||
device->ptr_a11y_data = g_new0 (ClutterPtrA11yData, 1);
|
||||
|
@ -1176,7 +1176,7 @@ clutter_interval_compute_value (ClutterInterval *interval,
|
||||
* g_object_set_property()
|
||||
*
|
||||
* Return value: (transfer none): a pointer to the computed value,
|
||||
* or %NULL if the computation was not successful
|
||||
* or %NULL if the computation was not successfull
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CLUTTER_KEYMAP_PRIVATE_H
|
||||
#define CLUTTER_KEYMAP_PRIVATE_H
|
||||
|
||||
#include "clutter/clutter-keymap.h"
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_keymap_set_lock_modifier_state (ClutterKeymap *keymap,
|
||||
gboolean caps_lock_state,
|
||||
gboolean num_lock_state);
|
||||
|
||||
#endif /* CLUTTER_KEYMAP_PRIVATE_H */
|
@ -21,29 +21,10 @@
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter-keymap-private.h"
|
||||
#include "clutter-keymap.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_CAPS_LOCK_STATE,
|
||||
PROP_NUM_LOCK_STATE,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[N_PROPS];
|
||||
|
||||
typedef struct _ClutterKeymapPrivate
|
||||
{
|
||||
gboolean caps_lock_state;
|
||||
gboolean num_lock_state;
|
||||
} ClutterKeymapPrivate;
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterKeymap, clutter_keymap,
|
||||
G_TYPE_OBJECT)
|
||||
G_DEFINE_ABSTRACT_TYPE (ClutterKeymap, clutter_keymap, G_TYPE_OBJECT)
|
||||
|
||||
enum
|
||||
{
|
||||
@ -53,76 +34,9 @@ enum
|
||||
|
||||
static guint signals[N_SIGNALS] = { 0, };
|
||||
|
||||
static void
|
||||
clutter_keymap_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterKeymap *keymap = CLUTTER_KEYMAP (object);
|
||||
ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CAPS_LOCK_STATE:
|
||||
g_value_set_boolean (value, priv->caps_lock_state);
|
||||
break;
|
||||
case PROP_NUM_LOCK_STATE:
|
||||
g_value_set_boolean (value, priv->num_lock_state);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_keymap_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterKeymap *keymap = CLUTTER_KEYMAP (object);
|
||||
ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CAPS_LOCK_STATE:
|
||||
priv->caps_lock_state = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_NUM_LOCK_STATE:
|
||||
priv->num_lock_state = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_keymap_class_init (ClutterKeymapClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->get_property = clutter_keymap_get_property;
|
||||
object_class->set_property = clutter_keymap_set_property;
|
||||
|
||||
obj_props[PROP_CAPS_LOCK_STATE] =
|
||||
g_param_spec_boolean ("caps-lock-state",
|
||||
"Caps lock state",
|
||||
"Caps lock state",
|
||||
FALSE,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_NUM_LOCK_STATE] =
|
||||
g_param_spec_boolean ("num-lock-state",
|
||||
"Num lock state",
|
||||
"Num lock state",
|
||||
FALSE,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
||||
|
||||
signals[STATE_CHANGED] =
|
||||
g_signal_new (I_("state-changed"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
@ -140,17 +54,13 @@ clutter_keymap_init (ClutterKeymap *keymap)
|
||||
gboolean
|
||||
clutter_keymap_get_num_lock_state (ClutterKeymap *keymap)
|
||||
{
|
||||
ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap);
|
||||
|
||||
return priv->num_lock_state;
|
||||
return CLUTTER_KEYMAP_GET_CLASS (keymap)->get_num_lock_state (keymap);
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_keymap_get_caps_lock_state (ClutterKeymap *keymap)
|
||||
{
|
||||
ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap);
|
||||
|
||||
return priv->caps_lock_state;
|
||||
return CLUTTER_KEYMAP_GET_CLASS (keymap)->get_caps_lock_state (keymap);
|
||||
}
|
||||
|
||||
PangoDirection
|
||||
@ -158,35 +68,3 @@ clutter_keymap_get_direction (ClutterKeymap *keymap)
|
||||
{
|
||||
return CLUTTER_KEYMAP_GET_CLASS (keymap)->get_direction (keymap);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_keymap_set_lock_modifier_state (ClutterKeymap *keymap,
|
||||
gboolean caps_lock_state,
|
||||
gboolean num_lock_state)
|
||||
{
|
||||
ClutterKeymapPrivate *priv = clutter_keymap_get_instance_private (keymap);
|
||||
|
||||
if (priv->caps_lock_state == caps_lock_state &&
|
||||
priv->num_lock_state == num_lock_state)
|
||||
return;
|
||||
|
||||
if (priv->caps_lock_state != caps_lock_state)
|
||||
{
|
||||
priv->caps_lock_state = caps_lock_state;
|
||||
g_object_notify_by_pspec (G_OBJECT (keymap),
|
||||
obj_props[PROP_CAPS_LOCK_STATE]);
|
||||
}
|
||||
|
||||
if (priv->num_lock_state != num_lock_state)
|
||||
{
|
||||
priv->num_lock_state = num_lock_state;
|
||||
g_object_notify_by_pspec (G_OBJECT (keymap),
|
||||
obj_props[PROP_NUM_LOCK_STATE]);
|
||||
}
|
||||
|
||||
g_debug ("Locks state changed - Num: %s, Caps: %s",
|
||||
priv->num_lock_state ? "set" : "unset",
|
||||
priv->caps_lock_state ? "set" : "unset");
|
||||
|
||||
g_signal_emit (keymap, signals[STATE_CHANGED], 0);
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ struct _ClutterKeymapClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
gboolean (* get_num_lock_state) (ClutterKeymap *keymap);
|
||||
gboolean (* get_caps_lock_state) (ClutterKeymap *keymap);
|
||||
PangoDirection (* get_direction) (ClutterKeymap *keymap);
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# Author : Simos Xenitellis <simos at gnome dot org>.
|
||||
# Author : Bastien Nocera <hadess@hadess.net>
|
||||
# Authos : Bastien Nocera <hadess@hadess.net>
|
||||
# Version : 1.2
|
||||
#
|
||||
# Notes : It downloads keysymdef.h from the Internet, if not found locally,
|
||||
|
@ -32,7 +32,8 @@
|
||||
* it has been paired, and it controls the allocation of its children.
|
||||
*
|
||||
* Any composite or container #ClutterActor subclass can delegate the
|
||||
* layouting of its children to a #ClutterLayoutManager.
|
||||
* layouting of its children to a #ClutterLayoutManager. Clutter provides
|
||||
* a generic container using #ClutterLayoutManager called #ClutterBox.
|
||||
*
|
||||
* Clutter provides some simple #ClutterLayoutManager sub-classes, like
|
||||
* #ClutterFlowLayout and #ClutterBinLayout.
|
||||
@ -41,7 +42,7 @@
|
||||
* The implementation of a layout manager does not differ from the
|
||||
* implementation of the size requisition and allocation bits of
|
||||
* #ClutterActor, so you should read the relative documentation
|
||||
* for subclassing #ClutterActor.
|
||||
* forr subclassing #ClutterActor.
|
||||
*
|
||||
* The layout manager implementation can hold a back pointer to the
|
||||
* #ClutterContainer by implementing the #ClutterLayoutManagerClass.set_container()
|
||||
@ -96,7 +97,7 @@
|
||||
*
|
||||
* |[
|
||||
* {
|
||||
* "type" : "ClutterActor",
|
||||
* "type" : "ClutterBox",
|
||||
* "layout-manager" : { "type" : "ClutterGridLayout" },
|
||||
* "children" : [
|
||||
* {
|
||||
|
@ -84,7 +84,7 @@ struct _ClutterLayoutManager
|
||||
* in newly written code.
|
||||
* @end_animation: virtual function; override to end an animation started
|
||||
* by clutter_layout_manager_begin_animation(). This virtual function is
|
||||
* deprecated, and it should not be overridden in newly written code.
|
||||
* deprecated, and it should not be overriden in newly written code.
|
||||
* @get_animation_progress: virtual function; override to control the
|
||||
* progress of the animation of a #ClutterLayoutManager. This virtual
|
||||
* function is deprecated, and it should not be overridden in newly written
|
||||
|
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